Tuesday, January 22, 2019

c - understanding of extern storage class

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.

No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...