views:

427

answers:

3

Anyone have a link to what the C++ standard says regarding a compiler removing global and static symbols? I thought you weren't guaranteed that the compiler will remove global symbols if they're not referenced. A colleague of mine asserts that if your global symbols are included in the main translation unit, those symbols will not be removed even if they're not referenced.

+3  A: 

Interestingly, all I can find on this in the C++2003 standard is this:

3.7.1 Static storage duration [basic.stc.static]

All objects which neither have dynamic storage duration nor are local have static storage duration. The storage for these objects shall last for the duration of the program (3.6.2, 3.6.3).

If an object of static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy may be eliminated as specified in 12.8.

This implies that the standard permits elimination of items in static storage if initialization and destruction of them have no side effects and they are otherwise unused.

If there's a more direct permission, I didn't see it (but maybe someone else will).

However, it should be noted that having the linker eliminate unused objects in the final image is a very common optimization.

Michael Burr
A: 

You're asking a question about linking, and although the C++ Standard says that linking should occur as the final phase of translation, it says nothing about how that should happen. For example, it says that function references are resolved, but it doesn't require them to be resolved by name, and it doesn't say what happens to the references after resolution.

To determine what symbols the compiler includes in the object code, and which ones the linker does or doesn't remove, you'll need to consult the documentation for the compiler and linker, respectively, that you're using.

Rob Kennedy
Linking _is_ in scope of the C++ standard. It's one of the final stages of compilation, in which Translation Units are combined. The wording differs, though. Similar to byte != octet
MSalters
Ah, you're right. Better now?
Rob Kennedy
A: 

It's this way i believe (we had a lengthy discussion on this earlier on stack overflow in a comment-thread):

  1. If the initialization or destructor of an object with namespace scope (that are objects with static storage duration) has no side-effects, the objet can be optimized out if there is no use of a function or object in its translation unit.
  2. For objects whose initialization or destruction cause side effects, then the compiler may not optimize that variable out, even if there is no use of objects or functions of its translation units.

In any case, the compiler has to initialize the objects before that use is done, but not necessarily before main. I did tests because someone at stackoverflow said that gcc effectively optimizes out initializations of objects having side effects if there is no such use. I tested that now, and I've seen gcc does not do that. Additionally, as i understand the Standard, it is not allowed to do so anyway.

It suffices if you just take the address of an object or function of the translation unit of the object you want to have initialized. To be on the safe side, better always do that, even for objects having initializations with side effects. Assuming your friend is right, i think for the translation unit of main, main is always seen as being used, so that condition immediately is satisfied. Rules can be found in 3.6.2p3, 3.7.1p2 and 3.2p2 (definition of use), 1.9p7 (definition of side-effect).

Johannes Schaub - litb