I have a few questions about the linkage from the following variables. By examples of 7.1.1/7 of C++03 and experimenting with compilers (Comeau, Clang and GCC), I came to th
I think in #3 you've made an error in your analysis. As far as I know, const
does not imply anything about linkage. I'm not sure how you're coming to the conclusion that the compiler makes the linkage internal. Most compilers will (as an optimization) replace all references to the const variable by the value it's been initialized to, so the symbol may not appear at all in the code.
And even if you didn't, it's clear from #1 that if something with internal linkage is subsequently declared with the extern
keyword that it remains with internal linkage. So I don't know why you would expect an error.
And if const
implied internal linkage, then #4 should be an error for the same reason #2 is.
Having both (e) and (f) in the same namespace scope is simply invalid, by §7.1.1/7 "The linkages implied by successive declarations for a given entity shall agree.".
This rule requires a diagnostic.
However, at least Comeau Online does not diagnose the violation.
Cheers & hth.,
EDIT: He he, I looked up DR 426, as mentioned in another answer here, and it seems those who drafted the proposed resolution, making it UB instead of diagnosable, were not aware of §7.1.1/7. I'm not going to comment on the issue or even raise it in comp.std.c++ because I found the standardization work to be far too political and nonsensical (mumbo-jumbo arguments) for me. But either way, the code's not valid.
const double pi1 = 3.14; // (e)
extern const double pi1; // (f) valid and 'pi1' is internal
My interpretation is as follows. When considering the linkage of a name we consider previous declarations as well as the one being interpreted at this point in the parse. This is why static int a; extern int a;
is OK, but extern int b; static int b;
is not.
On encountering the first declaration we note that pi1
is explicitly declared const
but neither explicitly declared extern
nor previously declared to have external linkage. This matches one of the options of 3.5/2 therefore pi1
has internal linkage.
On encountering the second declaration we ask is pi1
the name of an object that is explicitly declared const
but neither explicitly declared extern
nor [... blah ...]. I contend that it is because it was so declared at point (e). Sure, it isn't declared that way everywhere but in the same way a
was the name of an object declared static
when we were considering the extern int a;
declaration even though it wasn't declared static
everywhere. This, to me, means that the declaration (f) doesn't imply a different linkage from declaration (e).