Are Global Variables Extern by Default or Is It Equivalent to Declaring Variable with Extern in Global

Whether Global Variables in C, static or extern?

Global Variable in C by default corresponds to static storage class but has external linkage. Does this mean it is partially static and partially extern?

The English word “static” has muddled and multiple meanings in C, and, yes, the default for a variable declared outside a function is to have static storage duration and external linkage.

Because there are multiple concepts here and some mixed use of word meanings, we should clarify some terminology and formatting:

  • Use code style to refer to specific text in source code, such as the keyword static. When speaking of static storage duration or external linkage, “static” and “external” are mere English adjectives and should not be in code style.
  • “Global” means visible throughout an entire program. The C standard does not use this word for this purpose. It uses “external” to refer to things that are outside of (external to) any function. (But it also uses “external” for other purposes.) A global variable could not have internal linkage, because it would not be visible throughout the entire program.
  • A variable consists of an object (memory reserved for representing the value) and an identifier (the name). Storage duration is a property of the object. Linkage is a property of the identifier.

The English word “static” generally means unchanging. The C standard uses this word and the keyword static in multiple ways:

  • Static storage duration means the memory for an object is reserved throughout all of program execution.
  • Using the static keyword in a declaration, other than as below, both gives an object static storage duration and, in a declaration outside a function, gives the identifier internal linkage.
  • Using the static keyword inside subscript markers in a parameter declaration, as in void foo(int a[static 3]), indicates that the parameter points to at least the stated number of elements.
  • Static assertions, using _Static_assert, provide compile-time tests (which can help detect bugs or ensure a program is being compiled with expected settings).

These multiple uses are unfortunate and are due at least partly to the history of how the C language was developed.

Why do globals have external linkage by default?

It is true that x and z cannot be defined in another source file because they are already defined. They can however be declared in another file so that they may be used.

If you had the following in another source file:

extern int x;
extern int z;

Then you would be able to use both x and z in that source file.

Also, if your code was compiled by itself into an executable, the linking stage would fail because y was declared but not defined.

What does `extern` do when getting a global variable inside a block? (with a different variable defined with the same name)

The fact that the declaration extern int x; refers to int x; declared at file scope is an example of how linkage works. An identifier specifying an object or function may have one of the following linkages:

  • Identifiers with external linkage represent the same object or function in any translation unit (i.e. source file and included headers) in the program.
  • Identifiers with internal linkage represent the same object or function in one particular translation unit.
  • Identifiers with no linkage represent a distinct object and only exist in the scope in which they are declared.

In your example, int x; at file scope has external linkage because it was not declared with the static storage class specifier.

int x; declared in the outermost block of the main function has no linkage because there is no storage class specifier on it, so this declaration defines a new object which masks x declared at file scope.

Now you have extern int x; declared in a sub-block inside of main. Because this identifier is declared with extern, it is compared with the prior visible declaration, specifically x declared in block scope above it. Since this prior declaration has no linkage, this new identifier has external linkage (it would have internal linkage if the prior declaration had internal linkage). This is described in more detail in section 6.2.2p4 of the C standard:

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

And because it has external linkage, it refers to the same object as int x; declared at file scope.

Global variables in C are static or not?

If you do not specify a storage class (that is, the extern or static keywords), then by default global variables have external linkage. From the C99 standard:

§6.2.2 Linkages of identifiers

3) If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static, the identifier has internal linkage.

5) If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

So even if you don't specify the extern keyword, globals can still be accessed by other source files (so-called translation units), because they can still have an extern declaration for the same variable. If you use the static keyword to specify internal linkage, then even in the presence of an extern declaration for the same variable name in another source file, it will refer to a different variable.



Related Topics



Leave a reply



Submit