tags:

views:

52

answers:

2

I have a global list of function pointers. This list should be populated at startup. Order is not important and there are no dependencies that would complicate static initialization. To facilitate this, I've written a class that adds a single entry to this list in its constructor, and scatter global instances of this class via a macro where necessary. One of the primary goals of this approach is to remove the need for explicitly referencing every instance of this class externally, instead allowing each file that needs to register something in the list to do it independently. Nice and clean.

However, when placing these objects in a static library, the linker discards (or rather never links in) these units because no code in them is explicitly referenced. Explicitly referencing symbols in the compilation units would be counterproductive, directly contradicting one of the main goals of the approach. For the same reason, /INCLUDE is not an acceptable option, and /OPT:NOREF is not actually related to this problem.

Metrowerks has a __declspec directive for it, GCC has -force_load, but I cannot find any equivalent for MSVC.

A: 

If you don't want to #include anything, then this won't work, but if you can live with that, a common technique is to use a nifty-counter to call a function declared in the cpp file before main, which would then initialize any static objects in said file.

I've used this in projects that had a lot of objects that should go into factory. We had to have one file that #include each header that declared a class that must register itself in the factory. It's reasonably doable IMHO, as I strongly prefer writing source files as opposed to setting various linker/compiler options.

Another way (that doesn't seem to work via static libs, see comments) could be to declare something as __declspec(dllexport), which would force it's inclusion (__declspec works in executables too).

Marcus Lindblom
Well, the main purpose is exactly to avoid having to reference the global object anywhere outside the file it resides in. If it helps, this is for a unit testing framework; I _loathe_ the idea of referencing every unit test, from multiple libraries, in the same location, and it scales really poorly as the number of unit tests grow.Unfortunately, __declspec(dllexport) does nothing since this is a static library, not a DLL.
Peter C O Johansson
Thanks for clarifying. Hm. I thought __declspec would come in play when the lib was included into the actual module (dll/exe) that is loaded by the OS, but apparently I was wrong.
Marcus Lindblom
A: 

I think you want a #pragma optimize("", off) and #pragma optimize("", on) pair around these variable declarations. That will turn off the optimization which is discarding them.

Also remember preprocessor directives can't be part of macros. __pragma can be used for some things (and is designed specifically to be used in macros), but not everything, and the syntax is a little different. Not sure if it works with optimize.

Terry Mahaffey