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.