Why the following doesn't compile?
...
extern int i;
static int i;
...
but if you reverse the order, it compiles fine.
...
static int i;
extern int i;
...
What is going on here?
This is specifically given as an example in the C++ standard when it's discussing the intricacies of declaring external or internal linkage. It's in section 7.1.1.7, which has this exert:
static int b ; // b has internal linkage
extern int b ; // b still has internal linkage
extern int d ; // d has external linkage
static int d ; // error: inconsistent linkage
Section 3.5.6 discusses how extern
should behave in this case.
What's happening is this: static int i
(in this case) is a definition, where the static
indicates that i
has internal linkage. When extern
occurs after the static
the compiler sees that the symbol already exists and accepts that it already has internal linkage and carries on. Which is why your second example compiles.
The extern
on the other hand is a declaration, it implicitly states that the symbol has external linkage but doesn't actually create anything. Since there's no i
in your first example the compiler registers i
as having external linkage but when it gets to your static
it finds the incompatible statement that it has internal linkage and gives an error.
In other words it's because declarations are 'softer' than definitions. For example, you could declare the same thing multiple times without error, but you can only define it once.
Whether this is the same in C, I do not know (but netcoder's answer below informs us that the C standard contains the same requirement).