1

I have a configuration that has a library and a console application. They are pretty barebones at the moment. I am using Visual Studio 2010 and the library and console application are both statically linked to the Runtime. The console application also links to the library.

In the library, I can add this code in a source file:

class MyClass
{
public:
    MyClass()
    {
        printf("MyClass loaded\n");
    }
};

class MyClass2
{
public:
    static MyClass my_class;
};

MyClass MyClass2::my_class;

Now, my understanding is that my_class should be initialized at some point before main(). However, it never happens (as I do not get the printed message).

I can, however, get it to initialize using two different methods:

  1. Put the code in the console application instead. Doing that will invoke the printf() statement for certain.
  2. Modify MyClass2 to include a static function that is called from a global variable in the library and use that global variable in main() in the console application.

Example for #2 above:

Library file:

class MyClass
{
public:
    MyClass()
    {
        printf("MyClass loaded\n");
    }
};

class MyClass2
{
public:
    static MyClass my_class;
    static int Ping();
};

MyClass MyClass2::my_class;
int my_global = MyClass2::Ping();

Console application file:

extern int my_global;
int main()
{
    printif("%d", my_global);
}

Is Windows trying to help me by delay loading the linked in library's static variables?? Or is there some compiler setting I have set? This behavior was totally unexpected by me.

Anthony
  • 245
  • 1
  • 2
  • 10
  • It may be that your class is initialized before `stdout` (on which `printf` relies) is initialized? – Some programmer dude Apr 15 '14 at 08:51
  • 1
    Also, you might want to read [this old SO answer](http://stackoverflow.com/a/211307/440558). While it's not Windows specific it should still be enough to get you on the right track. – Some programmer dude Apr 15 '14 at 08:52
  • 1
    In the first case where you define `my_class` in the library project, do you also use `my_class` in the console application project? If not, the linker may decide not to include these in the final binary, because it thinks it's not required. Another question: the library file is a header or a cpp in the library project? – Alexander Tobias Bockstaller Apr 15 '14 at 09:11
  • It appears I got my answer. Thanks guys. To answer the questions anyway: Joachim: I ruled that out (sorry I didn't say) by using an exit(0) as well and a printf() in main still printed. Thanks for the link. Alexander: It was in CPP files. I believe you're on the right track as James also pointed out in his answer. – Anthony Apr 15 '14 at 09:39
  • @JoachimPileborg You do raise an interesting point. The C++ standard sets certain requirements for the initialization of `std::cout` (which the example almost certainly meets), but it says nothing about the initialization of `stdout`. – James Kanze Apr 15 '14 at 10:18

1 Answers1

2

Is the "library file" part of the final executable. If it is an object file in a statically linked library, it will only be part of the final executable if it resolves an otherwise unresolved external symbol. (This is the definition of a library.) If you never use any symbol in the object file, it won't be part of your executable, and it's as if the source file wasn't part of the application.

If the library is dynamically loaded, the situation is slightly different; a .dll is loaded as a unit (and not object file by object file, so it's not really a library), but if there are no unresolved symbols which would be resolved by loading the DLL, it won't be loaded either.

What you probably want to do is link against the object files, and not against a library. In Visual Studios, this means putting all of the sources in the same project. Or... you can link the library as a .dll, and then explicitly load it using LoadLibrary. (This is what we do for libraries which are only referenced because they have constructors of static objects which register themselves.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Thanks much. I considered that at one point and tried to even just "export" a random integer, and it didn't work. However, I *may* have been a victim of PCH or similar, as I tried it again now and it worked (of course, header files have also been updated, so maybe that's it too). Either way, this reply does make sense. Thanks! – Anthony Apr 15 '14 at 09:39