The answer to your first question is in section 6.2.2 of standard C:
4 For an identifier declared using the extern storage class specifier in the area in which the preliminary declaration of this identifier is visible, if an internal or external relationship is specified in the previous declaration, the binding of the identifier to the later declaration is the same as the link specified in the previous declaration. If the previous announcement was not visible, or if the link was not specified in the previous announcement, then the identifier has an external link.
Thus, the connection a is internal.
For your second question, the second sentence of the immediately following paragraph:
5 If the identifier declaration for a function does not have a storage class specifier, its binding is defined exactly as if it were declared extern storage class specifier. If the identifier declaration for an object has a file size and there is no storage class specifier, its relationship is external.
Since a is an object, not a function, declaring int a; without a storage class specifier gives a external connection. The same section says the following:
7 If within the translation unit the same identifier appears with both internal and external communication, the behavior is undefined.
Since in the second example a appears with both internal and external communication, this paragraph starts. One (especially useful) manifestation of undefined behavior is the error that your compiler produces.
All your examples can be understood by the following rules:
int a; always announces a with external communication;static int a; always declares a internal connection;extern int a; declares a through any kind of connected link or external link if it does not;- Two a declarations in the same area with different relationships give undefined behavior.
source share