Page 1 of 2

C on X86 : Static procedures can be set as globals

Posted: Fri Dec 08, 2023 7:49 am
by joukj
Hi all,

Consider the following:

Code: Select all

rumba-jj) cc/vers
VSI C x86-64 X7.4-843 (GEM 50XB9) on OpenVMS x86_64 V9.2-1  
rumba-jj) ty test1.c
typedef int (*Algo)(int dstSize);

static int jj( int i )
{
   return i;
}

static int jjj( int i )
{
   return i;
}

int jj1( int i )
{
  static const Algo decompress[2] = { jj, jjj};
   
   return decompress[ i ](5);
}
   8-DEC-2023 13:39:06
rumba-jj) ty test2.c
typedef int (*Algo)(int dstSize);

static int jj( int i )
{
   return 7*i;
}

static int jjj( int i )
{
   return 5*i;
}

int jj2( int i )
{
  static const Algo decompress[2] = { jj, jjj};
   
   return decompress[ i ](5);
}
   8-DEC-2023 13:39:11
rumba-jj) cc test1.c
rumba-jj) cc test2.c
rumba-jj) lib/crea jj.olb test1.obj,test2.obj
%LIBRAR-E-DUPGLOBAL, global symbol jjj from file $DSTM:[JOUKJ.test.bugs.c.stat_g
lob]test2.OBJ;1 already in library $DSTM:[JOUKJ.test.bugs.c.stat_glob]jj.olb;1

jjj (and jj) is defined static but appears as a global symbol in the object file. (the list-file (if created) gives it as a static).
I did not see this problem with the previous C-compiler. Also on AXP & IA64 I do not see this.
It is definitely a feature (???) of the new C-compiler on X86 to place sometimes static symbols as global symbols in the object file.

regards
Jouk

Re: C on X86 : Static procedures can be set as globals

Posted: Fri Dec 08, 2023 8:19 am
by craigberry
What happens when you compile /NOOPT. Does that make any difference?

Re: C on X86 : Static procedures can be set as globals

Posted: Fri Dec 08, 2023 8:30 am
by joukj
Exactly the same with /NOOP

Re: C on X86 : Static procedures can be set as globals

Posted: Fri Dec 08, 2023 12:09 pm
by tlovern
had to edit my response after looking at the example again.

The issue appears to be the librarian and module names.

Global names in the librarian are the entry points.

You cannot have two identically named modules in a library. There is no way to tell them apart.

For example a JJ.obj from a C compile and a JJ.obj from a fortran compile have the same global key value, "JJ" They will not coexist in the same library without renaming one of the routine names.

Re: C on X86 : Static procedures can be set as globals

Posted: Fri Dec 08, 2023 1:15 pm
by jonesd
tlovern wrote:
Fri Dec 08, 2023 12:09 pm
had to edit my response after looking at the example again.

The issue appears to be the librarian and module names.

Global names in the librarian are the entry points.

You cannot have two identically named modules in a library. There is no way to tell them apart.

For example a JJ.obj from a C compile and a JJ.obj from a fortran compile have the same global key value, "JJ" They will not coexist in the same library without renaming one of the routine names.
You can't have identically named module names, but the module name doesn't have to match the file name. Add
the following line to the top of jj.c
#pragma module jjc

Re: C on X86 : Static procedures can be set as globals

Posted: Fri Dec 08, 2023 7:13 pm
by hb
The OP has it right. Unfortunately it is a (known) bug. Under some conditions this compiler converts a "static function" to a "global function". That is, the symbol of the static function incorrectly becomes a global symbol instead of being a local symbol. Global symbols will make it into the global symbol table of an object library. Local symbols will not. I expect this bug will be fixed soon.

In his example there are no identical object module names.
The issue appears to be the librarian and module names.
No.
Global names in the librarian are the entry points.
Global symbol names in an object library are used to identify an object module. That's what the linker needs: resolving an undefined symbol "from a library". Actually it includes the identified object module into the image.
You cannot have two identically named modules in a library.
True. But trying so will NOT result in an error: librarian will replace the existing object module with the new one, because you said so - no matter in which object file the identically named object module was found.

You cannot have two identical symbols in the global symbol table of a library. Trying so will result in an error, the reported DUPGLOBAL.

Re: C on X86 : Static procedures can be set as globals

Posted: Sat Dec 09, 2023 9:08 am
by craigberry
Does changing the functions from "static" to "static inline" get you past the compiler bug?

Re: C on X86 : Static procedures can be set as globals

Posted: Sat Dec 09, 2023 11:28 am
by tlovern
jonesd wrote:
Fri Dec 08, 2023 1:15 pm
tlovern wrote:
Fri Dec 08, 2023 12:09 pm
had to edit my response after looking at the example again.

The issue appears to be the librarian and module names.

Global names in the librarian are the entry points.

You cannot have two identically named modules in a library. There is no way to tell them apart.

For example a JJ.obj from a C compile and a JJ.obj from a fortran compile have the same global key value, "JJ" They will not coexist in the same library without renaming one of the routine names.
You can't have identically named module names, but the module name doesn't have to match the file name. Add
the following line to the top of jj.c
#pragma module jjc
Correct, and I didn't see the use of Pragma in the code examples provided. (I may have missed them)

Re: C on X86 : Static procedures can be set as globals

Posted: Mon Dec 11, 2023 1:50 am
by joukj
Static inline does not help

Added in 1 minute 34 seconds:
It is clear that the module names are not the problem. If you analyze the object file the procedures are listed as global.

Re: C on X86 : Static procedures can be set as globals

Posted: Mon Dec 11, 2023 11:28 am
by tlovern
hb wrote:
Fri Dec 08, 2023 7:13 pm
The OP has it right. Unfortunately it is a (known) bug. Under some conditions this compiler converts a "static function" to a "global function". That is, the symbol of the static function incorrectly becomes a global symbol instead of being a local symbol. Global symbols will make it into the global symbol table of an object library. Local symbols will not. I expect this bug will be fixed soon.

In his example there are no identical object module names.
The issue appears to be the librarian and module names.
No.
Global names in the librarian are the entry points.
Global symbol names in an object library are used to identify an object module. That's what the linker needs: resolving an undefined symbol "from a library". Actually it includes the identified object module into the image.
You cannot have two identically named modules in a library.
True. But trying so will NOT result in an error: librarian will replace the existing object module with the new one, because you said so - no matter in which object file the identically named object module was found.

You cannot have two identical symbols in the global symbol table of a library. Trying so will result in an error, the reported DUPGLOBAL.
Not the first time I've been wrong in my understanding of what Librarian is doing, just anecdotal observations, which I misinterpreted. So, I learned something.