I ran across some legacy code that's failing to build on a newer compiler. The boiled down example:
int x;
extern "C" { int x }; // conflicts with C++ linkage above
// note: without the braces it would've been equivalent to:
// extern "C" { extern int x; }
//
// for reference, see the notes section here:
// http://en.cppreference.com/w/cpp/language/language_linkage#notes
The older compilers weren't flagging it, but both gcc (as of 4.1.2) and clang flag it.
Clang's output:
error: declaration of 'x' has different language linkage
GCC's output:
error: previous declaration of 'int x' with 'C++' linkage
error: conflicts with new declaration with 'C' linkage
This surprised me because the compiler doesn't mangle x
in any special way, and as far as I can tell nothing is different about the object file other than debug information (based on my admittedly shallow test with objdump/readelf)
My question: why is this an error if there's no functional difference?
As an aside, I'm not averse to changing the code; I wanted to know whether there was something more going on than just "the standard says this is ill formed".
I looked through the various *stack sites and mostly found questions on this topic relating to functions with conflicting linkage specifications.
I found my [first] answer in the gcc bugzilla database:
Whether my supposition is correct (about the functional difference between C/C++ linkage for POD variables) or not, it appears the error is intended to prevent bad style.
Then I found this article about storage class specifiers and one about language linkage. I didn't see anything in those articles conflicting with what I've learned so far; the 2nd one says: