C++ weird static/global issue with libraries

Started by
1 comment, last by Numsgil 16 years, 10 months ago
I'm having a very weird issue. I'm running MSVC 2005 in debug build mode. My class looks like this:

class ClassName
{
  static ClassName StaticInstance;

  //ctors etc.
};
ClassName ClassName::StaticInstance;

It's defined in a cpp file, there's no include file (I'm just trying to trick the compiler into generating an instance so I can run its ctor during the program initialization.) The file is part of a dll that another application calls at run time. I place this code snipet in the .cpp file I need it to go in, but the static variable never gets initialized. I try moving the code snipet to another .cpp file, and it works just fine. I move it back into the file it should go in, and it never gets initialed. Confused, I try setting up a static string. It never gets initialized in this file either (ctor is never called), but it does if I move it to a different file. I even tried taking off the static tag, so it was just a global. It seems that global/static variables weren't being initialized in this .cpp file. I try setting up an extern reference to the string variable in another class, and suddenly all my globals/statics in the file are working (their ctors are being called). I remove the extern reference totally and it stops working again. I try adding back in just the extern reference without the code that uses it, and it stops working. I go to the file in question during a debug, and I get the message "No symbols have been loaded for this document." As near as I can figure, it seems that the problem stems from the fact that no executing code is referencing these statics/globals, so the initialization of them is turned off. This is weird since the program is being built in debug mode and shouldn't remove unreferenced data (which this isn't really, since the ctor modifies data other active data uses). (and I did specifically check that "keep unreferenced data" option was checked). Is this a bug or a feature, and how can I fix it either way?
[size=2]Darwinbots - [size=2]Artificial life simulation
Advertisement
Hey,

I can't give you an answer without some more questions.

Is the .cpp located in a library and when you moved it did you move it to a .cpp file that was located in the main executable?

If that is the case then the reason is linking rules for libraries are different then linking of object files that go directly into the executable. For obj. files that get linked directly into the executable all symbols get linked in. Obj. files in the main executable get a free pass into the program while obj. files within libraries have to go through some processing. During the first phase of linking the linker will collect all the references through out all code then on the second phase if a library has a symbol that wasn't referenced it wont get merged into the final executable.

Point being you need to reference your variable to get it linked in or you need to have it a part of the executable and not a library.

-= Dave

Graphics Programmer - Ready At Dawn Studios
Quote:Original post by David Neubelt
Hey,

I can't give you an answer without some more questions.

Is the .cpp located in a library and when you moved it did you move it to a .cpp file that was located in the main executable?

Referencing it in the main application worked, so I tried moving the extern reference to a file in the library. That worked too. Simply having the extern isn't enough, you need to actually use it somewhere.

Quote:
If that is the case then the reason is linking rules for libraries are different then linking of object files that go directly into the executable. For obj. files that get linked directly into the executable all symbols get linked in. Obj. files in the main executable get a free pass into the program while obj. files within libraries have to go through some processing. During the first phase of linking the linker will collect all the references through out all code then on the second phase if a library has a symbol that wasn't referenced it wont get merged into the final executable.

Point being you need to reference your variable to get it linked in or you need to have it a part of the executable and not a library.

-= Dave


That's what I was thinking too, but if that's the case, it doesn't explain why referencing the one global/static causes all other globals/statics to get added too (even ones that have nothing to do with the referenced one).

Also, this is a dynamically linked library, so wouldn't that mean that the main executable doesn't modify what is/is not included in the library?

edit:
Did some experimenting. Calling any functions or globals in another .cpp file is enough to get the globals/statics in the file to initialize. Including the prototype isn't enough, though.
[size=2]Darwinbots - [size=2]Artificial life simulation

This topic is closed to new replies.

Advertisement