Bug#223391: gcc-3.2: Anonymous namespaces can sometimes still cause cross-object symbol conflicts
Package: gcc-3.2
Version: 1:3.2.3-0pre9
Severity: normal
The attached test program, when compiled with
make CXX=g++-2.95
produces this output:
creating test2.o
creating test1.o
starting
but when compiled with
make CXX=g++-3.2
produces this output:
creating test1.o
creating test1.o
starting
This is because C++ anonymous namespaces (namespaces created without names,
ie. namespace { ... };) are actually exported from object files using weak
symbols, and only one of the symbols is actually linked into the final
program. The weak symbols have funny auto-generated names that are intended
to avoid name conflicts between object files, but the name-generation scheme
used in gcc 3.2 is based on the *source* filename, which might be the same
for two different object files. In my example, the makefile does this:
g++-3.2 -c -o test1.o -DTEST='"test1.o"' testx.cc
g++-3.2 -c -o test2.o -DTEST='"test2.o"' testx.cc
This makes the compiler output different for the two object files, although
the symbol names end up being the same (as you can see with 'nm -D
test1.o').
Note that:
- gcc-2.95 (debian 2.95.4-0.01042) does *not* exhibit this problem; it
seems to use a random number for its random namespace symbol names.
- there is probably no reason to make the symbols from that namespace
anything other than file-local anyway. Anonymous namespaces are
explicitly not expected to be accessible from any other object.
Source code follows.
Have fun,
Avery
-- System Information
Debian Release: testing/unstable
Architecture: i386
Kernel: Linux insight 2.4.19 #1 mer sep 4 10:52:04 EDT 2002 i686
Locale: LANG=fr_CA, LC_CTYPE=fr_CA
Versions of packages gcc-3.2 depends on:
ii binutils 2.13.90.0.18-1.7 The GNU assembler, linker and bina
ii cpp-3.2 1:3.2.3-0pre9 The GNU C preprocessor
ii gcc-3.2-base 1:3.2.3-0pre9 The GNU Compiler Collection (base
ii libc6 2.3.2.ds1-10 GNU C Library: Shared libraries an
ii libgcc1 1:3.3-2 GCC support library
>>>>>>>>>>>>>>>>>>>>>>>> Makefile >>>>>>>>>>>>>>>>>
main: main.o test1.o test2.o
$(CXX) -o main $^
test%.o: testx.cc
$(CXX) -c -o $@ -DTEST='"$@"' $^
clean:
rm -f *.o *~ *.so main
>>>>>>>>>>>>>>>>>>>>>>>> main.cc >>>>>>>>>>>>>>>>>>>>>>
#include <stdio.h>
int main()
{
printf("starting\n");
return 0;
}
>>>>>>>>>>>>>>>>>>>>>>>> testx.cc >>>>>>>>>>>>>>>>>>>>>>>
#include <stdio.h>
namespace {
struct Blah {
Blah() { printf("creating %s\n", TEST); }
};
static Blah blah;
};
>>>>>>>>>>>>>>>>>>>>>> END >>>>>>>>>>>>>>>>>>>>
Reply to: