understanding of extern storage class
This question already has an answer here:
The variable a
is declared and defined as a global variable in the line:
int a = 20;
The extern
line just tells the main()
function scope that a
is defined in another place.
In this case, the use of extern
is not really necessary. You could just declare and define a
before the main()
function, and then main()
would be familiar with it.
Usually, you would use extern
when you want to use a variable or a function that was defined in another source file (and not just later in the same source file).
extern
is syntactically a "storage class" keyword. But there is no such storage class. C has "static storage", "dynamic storage ( malloc
, etc) and "automatic storage" (local variables, usually represented using a stack).
If an identifier is declared extern
inside a block scope, it means that the declaration refers to an external definition. If the entity being declared is an object, then it has static storage, simply because external objects have static storage. It can be a function too; functions aren't said to have storage.
In C, there is a concept called "linkage". Objects declared outside of any function at file scope, and functions, can have "external" or "internal" linkage.
If we have extern
in a block scope, as you have in the example program, there can be a prior declaration of the same name at file scope, or in a nested scope, like this:
static int x;
/* ... */
{
extern int x;
}
Here, the inner x
refers to the outer x
, and, in spite of being "extern", it has internal linkage because of the "static".
In a nutshell, extern
usually means "refer to the earlier declaration, and if there isn't one, declare this as an identifier with external linkage".
The word "external" refers to two separate concepts: the aforementioned "external linkage" and also to the meaning "outside of any function", as in "external declaration". Confusingly, "external declarations", like the static int x
above, can have "internal linkage"!
In your program, things are correct because the block scope extern
declaration of a
and the later int a = 20
, which are in separate scopes, happen to independently agree with each other.
The int a = 20;
is an external declaration, which is also an external definition (because of the initializer). Since in that scope, no prior declaration of a
is visible, it gets external linkage.
So, where is a
defined? It is defined as an object with external linkage, in the entire translation unit as a whole. That translation unit is what defines a
. a
is declared in every place of the program where a declaration appears; and its definition is also a declaration. It is declared in main
and also in the last line of the translation unit's source code.
A "declaration" is syntax which makes a name known in some scope. It's a concept that is active during the translation of a program. A "definition" is the fact that some object or function is provided in some translation unit. Translated units still provide definitions, but need not retain information about declarations. (Which is why when we make libraries, we provide header files with declarations in them!)
From the point of view of your main
function, that function doesn't "care" where a
is defined. It has declared a
in such a way that if a
is used, then an external definition of a
, with external linkage, must exist. That definition could come from anywhere: it could be in the same translation unit, or in another translation unit.
The C programming language has been designed to be one-pass, so that the compiler could process each line only once from top to bottom. So considering your program:
#include <stdio.h>
int main(){
extern int a;
printf("%dn",a);
return 0;
}
int a = 20;
The identifier a
is declared twice, and defined once.
Before the 4th line extern int a;
, the compiler doesn't know anything about the identifier a
. The declaration extern int a;
has the block scope within the function main
, and it declares the identifier a
as an int
and that its storage duration is static and linkage is external. So the compiler can write code that access a global identifier by name a
as an int
variable that could be defined in another module (external linkage). This is what the compiler does on line 5
when it is used in printf
.
Finally at line 9, int a = 20;
is another declaration and definition. This declares and defines a
as a int
with static storage duration, and external linkage.
If you'd put the int a = 20;
before the main
, the declaration extern int a;
would be useless, because it doesn't add anything. I tend to put my main
and other depending functions last in my source code, so that minimal amount of extra declarations are needed.
上一篇: extern变量是如何定义的?
下一篇: 了解外部存储类