Every Google search explains them as just "names for your variables", but I have a feeling there is a distinction between the identifier and the identifier's name. Is an identifier more like an object with attributes like name, scope, linkage, and an underlying object? I ask this because I ran into some trouble trying to read through the C standard. For instance, the snippet
int main(){
int x;
extern int x;
}
fails to compile whereas
int main(){
int x;
if(1){extern int x;}
}
compiles successfully. In this question, the failure of the first snippet is explained from 6.2.2.6 in the C standard, which states that local variables have no linkage. However, in the second snippet, the local variable still has no linkage and yet there is no conflict. Now, 6.2.2.4 states
For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.
My explanation would have been that this rule is in effect in both snippets, but in the first one, the uniqueness of the underlying object of x
triggers a constraint violation via 6.2.1.2 because the same identifier name is being used for two distinct objects with the same scope and name space. But this is not the explanation given in the answer to the question I linked earlier. In the second snippet, the linkage types are still conflicting, so does changing the scope of the extern
declaration change the visibility of the local declaration? What is the best way to think about linkage from the abstract point of view of the C standard (without using actual implementations like gcc or clang as illustration)?