https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70476
Bug ID: 70476 Summary: C++11: Function name declared in unnamed namespace extern "C" gets exernal linkage Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: sbergman at redhat dot com Target Milestone: --- My reading of the C++11-and-beyond Standard is that the name of a function with extern "C" language linkage declared in an unnamed namespace should have internal linkage: Per [basic.link], it has the same linkage as the enclosing unnamed namespace (i.e., internal). And [dcl.link]'s "A declaration directly contained in a linkage-specification is treated as if it contains the extern specifier..." is irrelevant, as even a function declared with the "extern" storage specifier in an unnamed namespace has internal linkage. (See also <https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/oyLCkCUKpfU> "Linkage of: namespace { extern "C" { void f() {} } }".) That is, with test.cc being void external01() {} extern void external02() {} static void internal03() {} extern "C" void external04() {} extern "C" { void external05() {} } extern "C" { extern void external06() {} } extern "C" { static void internal07() {} } namespace { void internal08() {} } namespace { extern void internal09() {} } namespace { static void internal10() {} } namespace { extern "C" void internal11() {} } namespace { extern "C" { void internal12() {} } } namespace { extern "C" { extern void internal13() {} } } namespace { extern "C" { static void internal14() {} } } all external* should have external linkage and all internal* should have internal linkage when compiled as C++11 or later. But (at least on Linux with recent GCC trunk) > $ gcc/trunk/inst/bin/g++ --version > g++ (GCC) 6.0.0 20160331 (experimental) > Copyright (C) 2016 Free Software Foundation, Inc. > This is free software; see the source for copying conditions. There is NO > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > > $ gcc/trunk/inst/bin/g++ -std=c++11 -c test.cc && nm test.o | grep -w T > 0000000000000015 T external04 > 000000000000001c T external05 > 0000000000000023 T external06 > 0000000000000046 T internal11 > 000000000000004d T internal12 > 0000000000000054 T internal13 > 0000000000000000 T _Z10external01v > 0000000000000007 T _Z10external02v shows that internal11--13 erroneously get external linkage.