views:

147

answers:

1

I'm playing with function-level linking in VC++. I've enabled /OPT:REF and /OPT:ICF and the linker is happy to eliminate all unused functions. Not so with variables.

The following code is to demonstrate the problem only, I fully understand that actually having code structured that way is suboptimal.

//A.cpp
SomeType variable1;

//B.cpp
extern SomeType variable1;
SomeType variable2;
class ClassInB {
 //actually uses variable1
};

//C.cpp
extern SomeType variable2;
class ClassInC {
 //actually uses variable2;
};

All those files are compiled into a static lib. The consumer project only uses ClassInC and links to the static library. Now comes the VC++ 9 linker.

First the linker sees that C.obj references variable2 and includes B.obj. B.obj references variable1, so it includes A.obj. Then the unreferenced stuff elimination phase starts. It removes all functions in A.obj and B.obj, but not the variables. Both variable and variable2 are preserved together with their static initializers and deinitializers. That inflates the image size and introduces a delay for running the initializers and deinitializes.

The code above is oversimplified, in actual code I really can't move variable2 into C.cpp easily. I could put it into a separate .cpp file, but that looks really dumb. Is there any better option to resolve the problem with Visual C++ 9?

+2  A: 

The MSDN (see the Arguments section, REF | NOREF arguments, 4th paragraph) specifies that You have to explicitly mark data as a COMDAT; use __declspec(selectany). for the linker to remove said unused data when using /OPT:REF.

Have you tried and had any chance with __declspec(selectany) ?

RaphaelSP
direct link? ???
shoosh
@shoosh Good idea. Answer edited.
RaphaelSP