public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* bug with initialisation of global variables in a library (C++, gcc 2.95.2)
@ 2001-04-26  7:08 Kris Thielemans
  2001-04-26 10:03 ` Fergus Henderson
  0 siblings, 1 reply; 3+ messages in thread
From: Kris Thielemans @ 2001-04-26  7:08 UTC (permalink / raw)
  To: gcc

[-- Attachment #1: Type: text/plain, Size: 1717 bytes --]

Hi,

I have a global variable in a stand-alone .cpp file (the variable is static
but doesn't need to be to reproduce the bug). Initialisation of this
variable should occur by calling a constructor. (This should happen before
the main function is started).

However, this works only when I link with the corresponding .o file. If I
put the .o file in a library first (using ar), the constructors are NOT
called anymore.

Attached are 2 .cpp files and a Makefile to reproduce the problem. The
easiest way to do this is by typing:
	make -f Makefile.globalvarinit run

This will compile the .o files, make the library and link in 2 ways:
	g++ -o globalvarinitnolib globalvarinitmain.o globalvarinit.o
	g++ -o globalvarinitlib globalvarinitmain.o globalvarinit.a
And then run the 2 executables. You probably will see the following output

no lib version
./globalvarinitnolib
Executing default constructor
executing 'int' constructor with value 4
In main program
lib version
./globalvarinitlib
In main program

That is, the 'lib' version does not execute the constructors.

Test systems:
SuSE Linux with gcc 2.95.2
Solaris with gcc 2.95.2
cygwin on NT with gcc 2.95.3-3


Note that the obvious work-around to keep it out of the library does not
really work in my actual program, because the constructor needs things from
the library, and the library needs the global variables, so I get unresolved
linking errors.

Can anyone help? Is this a known bug?


Kris Thielemans
(kris.thielemans@ic.ac.uk)
Imaging Research Solutions Ltd
Cyclotron Building
Hammersmith Hospital
Du Cane Road
London W12 ONN, United Kingdom

Phone on :   +44 (020)8383 3731
FAX on :     +44 (020)8383 2029

web site address:
http://www.irsl.org/~kris

[-- Attachment #2: globalvarinit.cpp --]
[-- Type: text/x-c++, Size: 256 bytes --]

#include <iostream>

class A
{
public:
  A() 
  {
    std::cerr << "Executing default constructor\n";
  }
  A(int a)
  {
    std::cerr << "executing 'int' constructor with value " << a << std::endl;
  }
};

static const A dummy;
static const A dummy2(4);


[-- Attachment #3: globalvarinitmain.cpp --]
[-- Type: text/x-c, Size: 85 bytes --]

#include <iostream>

int main()
{
  std::cerr << "In main program\n";
  return 0;
}


[-- Attachment #4: Makefile.globalvarinit --]
[-- Type: text/x-makefile, Size: 485 bytes --]

all: globalvarinitnolib globalvarinitlib

run: all
	@echo no lib version 
	./globalvarinitnolib 
	@echo lib version
	./globalvarinitlib

globalvarinitnolib: globalvarinitmain.o globalvarinit.o
	g++ -o globalvarinitnolib globalvarinitmain.o globalvarinit.o

globalvarinitlib: globalvarinitmain.o globalvarinit.a
	g++ -o globalvarinitlib globalvarinitmain.o globalvarinit.a

globalvarinit.a: globalvarinit.o 
	ar r globalvarinit.a globalvarinit.o

%.o: %.cpp
	g++ -c $(CFLAGS) -o  $@ $< 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: bug with initialisation of global variables in a library (C++, gcc 2.95.2)
  2001-04-26  7:08 bug with initialisation of global variables in a library (C++, gcc 2.95.2) Kris Thielemans
@ 2001-04-26 10:03 ` Fergus Henderson
  2001-04-27  6:00   ` Kris Thielemans
  0 siblings, 1 reply; 3+ messages in thread
From: Fergus Henderson @ 2001-04-26 10:03 UTC (permalink / raw)
  To: Kris Thielemans; +Cc: gcc

On 26-Apr-2001, Kris Thielemans <kris.thielemans@ic.ac.uk> wrote:
> I have a global variable in a stand-alone .cpp file (the variable is static
> but doesn't need to be to reproduce the bug). Initialisation of this
> variable should occur by calling a constructor. (This should happen before
> the main function is started).
> 
> However, this works only when I link with the corresponding .o file. If I
> put the .o file in a library first (using ar), the constructors are NOT
> called anymore.

That's because the .o file is not being linked into your program.

If you put an object file in a (static) library, and link to the
library, then that object file will only be linked into your program if
it is referenced.  This is a feature, not a bug ;-)
If, as in your example, the object file only defines symbols with
internal linkage (e.g. global variables declared `static'), then there
is no way that it can be referenced.

One way to avoid this problem is to use shared libraries rather
than static libraries.

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: < http://www.cs.mu.oz.au/~fjh >  |     -- the last words of T. S. Garp.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: bug with initialisation of global variables in a library (C++, gcc 2.95.2)
  2001-04-26 10:03 ` Fergus Henderson
@ 2001-04-27  6:00   ` Kris Thielemans
  0 siblings, 0 replies; 3+ messages in thread
From: Kris Thielemans @ 2001-04-27  6:00 UTC (permalink / raw)
  To: Fergus Henderson; +Cc: gcc, p.dev

Dear Fergus,

thanks a lot for the clear explanation.

I wonder if I can ask you some questions then on how to solve my problem. I
guess this doesn't really belong on the gcc mailing list, but more in a
general C++ forum. I'd be happy to transfer the discussion to say the C++
news group.

I'm not familiar with shared libraries (can anyone point me to some doc?)
but I presume they are OS dependent, which is a major problem for our
project. For one thing, I think that on Windows, DLL's have problems with
initialisation of static variables as well. So, I'm not very eager to go
this route.

Let me describe what we're trying to do. I have a hierarchy where all
children register themselves in a list (kept by the root of the hierarchy).
At run-time, the user can then say which of the children (s)he actually
wants to use. (In more or less standard jargon, each child has a factory,
and I keep a FactoryRegistry somewhere).

The intention is that the registration in the list of factories happens
automatically: each child will have a .o file. As soon as you link with it,
it should add the child to the registry. I use a well-known trick for this
by having a RegisterIt class with a constructor that will add a factory to
the registry. So, the only thing I have to do is to have a (static) variable
of type RegisterIt somewhere in the child's .cxx.

Hopefully you can now see why I had the problem I mentioned. Indeed, nowhere
in the .cpp, .h files, any of the children gets explicitly mentioned (except
of course in the child's own files).

The only alternative to shared libraries I now see to solve my problem is to
have somewhere in a .cpp file, a list of all possible children in some form.
Either as (a) global variables again, I then have to link with that .o file
explicitly (i.e. not in a library), or (b) in function which I'd have to
call in main().
I severely dislike this solution, as it means maintaining a file with all
possible children (and I'll have different hierarchies which use the same
philosophy).

Or is there another solution?

Thanks again,
and feel free to tell me I should ask this question somewhere else.

Kris Thielemans
(kris.thielemans@ic.ac.uk)
Imaging Research Solutions Ltd
Cyclotron Building
Hammersmith Hospital
Du Cane Road
London W12 ONN, United Kingdom

Phone on :   +44 (020)8383 3731
FAX on :     +44 (020)8383 2029

web site address:
http://www.irsl.org/~kris

>
>
> On 26-Apr-2001, Kris Thielemans <kris.thielemans@ic.ac.uk> wrote:
> > I have a global variable in a stand-alone .cpp file (the
> variable is static
> > but doesn't need to be to reproduce the bug). Initialisation of this
> > variable should occur by calling a constructor. (This should
> happen before
> > the main function is started).
> >
> > However, this works only when I link with the corresponding .o
> file. If I
> > put the .o file in a library first (using ar), the constructors are NOT
> > called anymore.
>
> That's because the .o file is not being linked into your program.
>
> If you put an object file in a (static) library, and link to the
> library, then that object file will only be linked into your program if
> it is referenced.  This is a feature, not a bug ;-)
> If, as in your example, the object file only defines symbols with
> internal linkage (e.g. global variables declared `static'), then there
> is no way that it can be referenced.
>
> One way to avoid this problem is to use shared libraries rather
> than static libraries.
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2001-04-27  6:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-04-26  7:08 bug with initialisation of global variables in a library (C++, gcc 2.95.2) Kris Thielemans
2001-04-26 10:03 ` Fergus Henderson
2001-04-27  6:00   ` Kris Thielemans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).