I get that in C, variable definitions and declarations are done similarly except when we use the keyword extern, for eg in the following code:
extern int i;
int main () {
..
int i = 1;
..
}
I know that 'i' is declared outside 'main' but memory for it is allocated inside 'main'. I have two questions: (i) Is i a stack variable or a variable on the data segment (global variable)? (ii) What is i's scope? Can it be seen outside the above .c file if executables of both files are linked together at runtime, or do we need the extern int i; declaration in each file?
Please help? I am not familiar with languages other than C/C++; hence I am having a hard time understanding the difference between variable definition and variable declaration.
extern int i;
declares, but does not define i
. If this i
is used and there is no definition of it somewhere, linking would generally fail. If it did not have the extern
, so it just said int i;
or int i = 0;
, it would define i
. (The former is a tentative definition, which acts a default if there is no non-tentative definition.)
Since the int i;
is inside a block (a sequence of statements enclosed by {
and }
, in this case the block that defines main
), it defines a new object. The name i
refers to different things outside main
and inside this block (but after the definition int i;
).
The scope of the i
declared by extern int i;
is the entire file from its declaration to the end. (That scope includes the block in main
, but this i
is hidden by the int i;
inside the block. Technically, the scope of the first i
includes that region—it is present but hidden and inaccessible.) Declaring names with extern
does not extend their scope beyond the current file. Rather, it gives them linkage, which means they can made to refer to the same object declared with the same name in another file.
The scope of the i
declared by int i;
is from its declaration to the end of the block it is declared in.
The i
defined inside main
is generally allocated on the stack by common compilers, if it is actually needed. (If the program does not actually use it, or the compiler can eliminate uses of it by optimization or fold them into other expressions, it may not need to actually allocate any stack space for it.) The object referred to by this i
has no relationship to any object referred to by i
outside of the block.