The following snippet works fine
extern int i;
int i;
int main(){
return 0;
}
Here what I got is, 'i' is declared and then defined. Since there is only one definition so thats perfectly fine.
int main(){
extern int i;
int i;
return 0;
}
Now, the above one gives the following error
new.cpp: In function ‘int main()’:
new.cpp:5:6: error: redeclaration of ‘int i’
int i;
^
new.cpp:4:13: note: previous declaration ‘int i’
extern int i;
Whats the problem here? Here also there is single definition of 'i'.
To understand the difference, you need to get familiar with a concept called tentative definition in C. To quote the C standard:
C11, draft, §6.9.2, External object definitions
What you have in the first snippet is only a tentative definition for
i
. You can have as many tentative definitions for an object as you want (but only one definition is allowed):is valid.
Here,
i
has external linkage and tentatively defined. Ifi
is defined in somewhere in the same translation unit, then that'll be the actual definition ofi
. If there's no other definition ofi
is found in the translation unit, then this becomes the full definition as if it was defined like:But the second snippet
int i;
is not a tentative definition. Only objects with external linkage can be defined tentatively. In second snippet, The declarationextern int i;
saysi
is defined elsewhere with external linkage. But the next lineint i;
saysi
is defined with no linkage (local automatic variables do not have any linkage -- this is not a tentative definition). So there's a conflict of definition fori
. Hence, the first one snippet is fine but second isn't.In the second case, there are two declarations of
i
in one scope. One says "there is a variablei
defined outside this function"; the other says "there is a variablei
defined inside this function". Without a new scope, that isn't allowed.The rules are different inside and outside functions.
Note that you could use:
This compiles OK (unless you include
-Wshadow
in your compilation options when using GCC or Clang), and produces57
and37
on the output (as pointed out by CoffeeAndCode in a comment).See also How do I use
extern
to share variables between source files?