Edit
In both C and C++, the presence of extern
indicates that the first declaration is not a definition. Therefore, it just makes the name available in the current translation unit (anyone who includes the header) and indicates that the object referred to has external linkage - i.e. is available across all the translation units making up the program. It's not saying that the object is necessarily located in another translation unit - just that 'this line isn't the definition'.
End edit
In C, the extern
is optional. Without it, the first declaration is a 'tentative definition'. If it were not for the later definition (which is unambiguously a definition because it has an initializer), this would be treated as a definition (C99 6.9.2). As it is, it's just a declaration and does not conflict.
In C++, the extern
is not optional - without it, the first declaration is a definition (C++03 3.1) which conflicts with the second.
This difference is explicitly pointed out in Annex C of C++:
"Change: C++ does not have “tentative definitions” as in C
E.g., at file scope,
int i;
int i;
is valid in C, invalid in C++."