Can a Variable Be Declared Both Static and Extern

Can a variable be declared both static and extern?

This is specifically given as an example in the C++ standard when it's discussing the intricacies of declaring external or internal linkage. It's in section 7.1.1.7, which has this exert:

static int b ; // b has internal linkage
extern int b ; // b still has internal linkage

extern int d ; // d has external linkage
static int d ; // error: inconsistent linkage

Section 3.5.6 discusses how extern should behave in this case.

What's happening is this: static int i (in this case) is a definition, where the static indicates that i has internal linkage. When extern occurs after the static the compiler sees that the symbol already exists and accepts that it already has internal linkage and carries on. Which is why your second example compiles.

The extern on the other hand is a declaration, it implicitly states that the symbol has external linkage but doesn't actually create anything. Since there's no i in your first example the compiler registers i as having external linkage but when it gets to your static it finds the incompatible statement that it has internal linkage and gives an error.

In other words it's because declarations are 'softer' than definitions. For example, you could declare the same thing multiple times without error, but you can only define it once.

Whether this is the same in C, I do not know (but netcoder's answer below informs us that the C standard contains the same requirement).

static variable followed by extern in the same file

You can declare a variable static then extern, but not extern then static. The result is that the global a still has internal linkage. There is a very similar example (using b as the variable name) in the language standard doc, section [dcl.stc], that states this.

Why won't extern link to a static variable?

The whole and entire purpose of static is to declare that a variable is private to the source file that it is declared in. Thus, it is doing precisely its job in preventing a connection from an extern.

Keep in mind that there are four flavors of file-scope variable definition:

  1. int blah = 0; — blah is defined in this file and accessible from other files. Definitions in other files are duplicates and will lead to errors.
  2. extern int blah; — blah must be defined elsewhere and is referenced from this file.
  3. int blah; — This is the moral equivalent of FORTRAN COMMON. You can have any number of these in files, and they are all resolved by the linker to one shared int. (*)
  4. static int blah; (optionally with an initializer) — This is static. It is completely private to this file. It is not visible to externs in other files, and you can have many different files that all declare static TYPE blah;, and they are all different.

For the purists in the audience: 'file' = compilation unit.

Note that static inside functions (not at file scope) are even more tightly scoped: if two functions declare static int bleh = 0; even in the same file, they are unrelated.

(*): for those of you not familiar: in the usual pattern, one compilation unit has to define a global variable, and others can reference it. It 'lives' in that compilation unit. In case (3), above, no file (or all the files) defines it. If two files say int blah = 0;, the linker will complain of multiple definitions. If two files say int blah; the linker cheerfully creates a single global int and causes all the code to refer to it.

What is the difference between static and extern in C?

From http://wiki.answers.com/Q/What_is_the_difference_between_static_and_extern:

The static storage class is used to declare an identifier that is a local variable either to a function or a file and that exists and retains its value after control passes from where it was declared. This storage class has a duration that is permanent. A variable declared of this class retains its value from one call of the function to the next. The scope is local. A variable is known only by the function it is declared within or if declared globally in a file, it is known or seen only by the functions within that file. This storage class guarantees that declaration of the variable also initializes the variable to zero or all bits off.

The extern storage class is used to declare a global variable that will be known to the functions in a file and capable of being known to all functions in a program. This storage class has a duration that is permanent. Any variable of this class retains its value until changed by another assignment. The scope is global. A variable can be known or seen by all functions within a program.

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.

static and extern global variables in C and C++

Global variables are not extern nor static by default on C and C++.
When you declare a variable as static, you are restricting it to the current source file. If you declare it as extern, you are saying that the variable exists, but are defined somewhere else, and if you don't have it defined elsewhere (without the extern keyword) you will get a link error (symbol not found).

Your code will break when you have more source files including that header, on link time you will have multiple references to varGlobal. If you declare it as static, then it will work with multiple sources (I mean, it will compile and link), but each source will have its own varGlobal.

What you can do in C++, that you can't in C, is to declare the variable as const on the header, like this:

const int varGlobal = 7;

And include in multiple sources, without breaking things at link time. The idea is to replace the old C style #define for constants.

If you need a global variable visible on multiple sources and not const, declare it as extern on the header, and then define it, this time without the extern keyword, on a source file:

Header included by multiple files:

extern int varGlobal;

In one of your source files:

int varGlobal = 7;

Are static class variables the same as extern variables, only with class scope?

Yes, both have static storage duration and external linkage; they have essentially the same run-time properties, only differing in (compile-time) visiblity.



Related Topics



Leave a reply



Submit