This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Changed resolution of anonymous namespace extern from gcc 3.4.2 to 4.1.0
- From: Earl Chew <earl_chew at agilent dot com>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 15 Sep 2008 22:46:40 -0700
- Subject: Changed resolution of anonymous namespace extern from gcc 3.4.2 to 4.1.0
Consider:
foo.h
#ifndef FOO_H
#define FOO_H
namespace { extern const char f[]; }
#endif
foo.cpp
#ifndef FOO_H
#error
#endif
namespace { const char f[] = "abc"; }
When used with precompiled headers:
% gcc -x c++-header foo.h -o foo.h.gch
% gcc -Winvalid-pch -S -include foo.h foo.cpp
% cat foo.s
Using 3.4.2, I get:
.file "foo.cpp"
.section .rodata
.align 2
.type _ZN36_GLOBAL__N_foo_cpp_00000000_7074E0CA1fE, @object
.size _ZN36_GLOBAL__N_foo_cpp_00000000_7074E0CA1fE, 4
_ZN36_GLOBAL__N_foo_cpp_00000000_7074E0CA1fE:
.string "abc"
.ident "GCC: (GNU) 3.4.2 (mingw-special)"
Using 4.1.0, I get:
.file "foo.cpp"
.globl _ZN34_GLOBAL__N_foo.h_00000000_F74D89311fE
.section .rodata
.type _ZN34_GLOBAL__N_foo.h_00000000_F74D89311fE, @object
.size _ZN34_GLOBAL__N_foo.h_00000000_F74D89311fE, 4
_ZN34_GLOBAL__N_foo.h_00000000_F74D89311fE:
.string "abc"
.ident "GCC: (GNU) 4.1.0"
.section .note.GNU-stack,"",@progbits
The behaviour with 3.4.2 was "expected" in the sense that I could
use the precompiled header repeatedly, and have
_ZN36_GLOBAL__N_foo_cpp_00000000_7074E0CA1fE resolved locally in
each object file.
Now that _ZN36_GLOBAL__N_foo_cpp_00000000_7074E0CA1fE is marked
.globl in 4.1.0, this fails miserably because the linker now
gets upset that there are many global definitions of
_ZN36_GLOBAL__N_foo_cpp_00000000_7074E0CA1fE.
In 4.1.0 the variable is now associated with foo.h (the site
of the extern declaration), whereas in 3.4.2 the variable was (more
correctly?) associated with foo.cpp (the site of the definition).
Can anyone point me to the patch, or region to patch, to recover
the old behaviour?
I can't make up my mind whether the new behaviour is incorrect,
or whether the old behaviour should never have been supported.
I am somewhat swayed by the fact that my previously working
program no longer compiles :-(
I note that if the program is simplified to:
bar.cpp
namespace { extern const char f[]; }
namespace { const char f[] = "abc"; }
then both 3.4.2 and 4.1.0 produce code which attaches
.globl to _ZN36_GLOBAL__N_bar_cpp_00000000_6AEC7CA11fE:
.file "bar.cpp"
.globl _ZN36_GLOBAL__N_bar_cpp_00000000_6AEC7CA11fE
.section .rodata
.align 2
.type _ZN36_GLOBAL__N_bar_cpp_00000000_6AEC7CA11fE, @object
.size _ZN36_GLOBAL__N_bar_cpp_00000000_6AEC7CA11fE, 4
_ZN36_GLOBAL__N_bar_cpp_00000000_6AEC7CA11fE:
.string "abc"
.ident "GCC: (GNU) 3.4.2 (mingw-special)"
.file "bar.cpp"
.globl _ZN36_GLOBAL__N_bar.cpp_00000000_CC9707B81fE
.section .rodata
.type _ZN36_GLOBAL__N_bar.cpp_00000000_CC9707B81fE, @object
.size _ZN36_GLOBAL__N_bar.cpp_00000000_CC9707B81fE, 4
_ZN36_GLOBAL__N_bar.cpp_00000000_CC9707B81fE:
.string "abc"
.ident "GCC: (GNU) 4.1.0"
.section .note.GNU-stack,"",@progbits
Any help would be appreciated.
Earl