extern int i = 14;
Works, if defined in the file where it is used.
It is confusing though, an extern token should only indicate declaration not definition.
I guess the compiler assumes that because there is an assignment, the extern keyword should be obviated, instead of throwing a compiler error.
It's not the compiler assuming anything, it's a rule in the standard. extern is not ignored. extern explicitly specifies the scope of the variable (which can be static, extern, auto, and register). That's why in global scope, you cant use extern and static within the same definition. Most of the time it's not used, just like most of the time we don't write "signed int".
Actually, that is not true at all. Fir understood it right. extern simply imports a variable or function defined in another translation unit(code file), in other words it is a linkage process, the scope will stay file based, and the duration program-wise(some books call it static, but I find it to be a horrible name.)
The proper term is "storage class". Extern specifies a storage class. You're right that declaring a variable in a function with extern does not make that variable local. But it does mean that the variable must be defined elsewhere in the program with extern storage class.
Really there are four uses of extern in C:
extern int i; // declares a variable with external linkage.
extern int i=0; // defines a variable with external linkage, just like if extern wasn't there. A program can only have one definition of such a variable.
extern int foo(); //declares a function with external linkage. As above, extern can be and usually is omitted.
extern void foo(){} //defines a function with external linkage. As above function, except this is a definition.
In the last three cases, extern can be replaced with static, to give the symbol internal linkage; extern and static are mutually exclusive. If you replace extern with static in the first case, it becomes a definition. Likewise extern cannot be used together with auto and register, the two storage classes of local variables. Consider:
void foo(){
int i;//defines an "automatic" or stack variable.
auto int j; //same as above. Not valid C++11.
register int k;//defines a register variable. Behaves the same as above, but the programmer intends the variable to be in a register. Same as above on widespread desktop compilers.
static int x; //defines a global variable, not accessible outside the function.
extern int y; //declares a global with external linkage.
}
static int y;//Error. clashes with extern int y above.
In no case can the same variable or function have more than one storage class.
There is one other rule however:
static int i;
extern int i;//declares i with internal linkage, referring to the above definition.