This was discovered on gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110) and verified still an issue in gcc version 3.3.3 configured with ../gcc- 3.3.3/configure having thread model:posix.
We discovered this issue in combatting an issue with binary reproducibility. Some early questions can be found in the thread "binary reproducibility and c++ default allocators" in gcc-help, though the issue is no longer believed to be related with the standard library and, although an issue for us, the bug report is not concerning binary reproducibility. The issue can be illustrated in a set of 3 very small files which compile in two translation units. The three files look like: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // binaryTest.h class SomeClass { public: SomeClass(unsigned const& value) : someMember_(value) {} private: unsigned someMember_; }; static SomeClass someThing(23); -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // binaryTest.cpp #include "binaryTest.h" int main() {} -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // other.cpp #include "binaryTest.h" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- This is compiled using the commandline: g++ -Wall --save-temps binaryTest.cpp other.cpp which gives the preprocessed output: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // binaryTest.ii # 3 "binaryTest.cpp" # 1 "binaryTest.h" 1 # 36 "binaryTest.h" class SomeClass { public: SomeClass(unsigned const& value) : someMember_(value) {} private: unsigned someMember_; }; static SomeClass someThing(23); # 4 "binaryTest.cpp" 2 int main() { } -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // other.ii # 2 "other.cpp" # 1 "binaryTest.h" 1 # 36 "binaryTest.h" class SomeClass { public: SomeClass(unsigned const& value) : someMember_(value) {} private: unsigned someMember_; }; static SomeClass someThing(23); # 3 "other.cpp" 2 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- This generates a symbol in the symbol table for the static variable which can be seen in the assembly output. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- _GLOBAL_.I.__9SomeClassRCUiother.cppeXJKrb: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- The same thing occurs if the variable is const, so it appears to be an issue with internal linkage symbols generally. As soon as one places a -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void f() {} -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- into other.cpp after the include, the symbol stops being generated in the assembly output. For some reason, the absence of executable code being compiled prevents elimination of internal linkage tokens from the symbol list. This bug does not occur for primitive types, presumably because of inlining. If more information is desired, I have a shell script and a configurable testBinary.h that demonstrates the problem for various const and static classes including standard library objects at file-scope. -- Summary: non-primitive types at file scope with internal linkage generate symbols when executable code absent Product: gcc Version: 3.3.3 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: galathaea at excite dot com CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20298