Static and Extern Global Variables in C and C++

Extern for Global and static global variables

Could anyone please explain how is it possible to use extern for
static global variable in c++?

No, it is not possible. For more details, please continue reading.

You can not use static global in other file even if you use extern (If I rephrase extern and static are conflicting specifiers)

But life time of static global is throughout the life of program.

The only way to use static in different compilation unit (source file) is to pass the address of this static variable to other file and use it by dereferencing the pointer.

If i have a header file with both global and static global variables
and i include it in my source file ans use extern for both and print
values its printing

static global This works because difference instances of variable is created for each source file. So if you change the value of variable in one of the file, it won't be reflected in other source file because physical location of both files are different.

non-static global extern int global is a declaration which goes into each source file via header file. All of them are lodged at physically same location. So if you change its value in one of the file, it would be reflected in other files also.


Further readings: storage duration

Internal linkage. The name can be referred to from all scopes in the
current translation unit.
Any of the following names declared at
namespace scope have internal linkage variables, functions, or
function templates declared static

And

external linkage. The name can be referred to from the scopes in the other translation units. Variables and functions with external
linkage also have language linkage, which makes it possible to link
translation units written in different programming languages.

variables and functions not listed above (that is, functions not
declared static, namespace-scope non-const variables not declared
static, and any variables declared extern)

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;

When to use static keyword before global variables?

static renders variable local to the file which is generally a good thing, see for example this Wikipedia entry.

How to globaly initialize variable in c and what is the difference between static and extern?

The scope of variable means: Where can it be seen (aka where does it exist) and thereby be accessed.

The scope of a variable depends on where in the code it is defined.

A variable gets global scope when it is defined outside a function. The keyword static can limit the scope of a global variable so that it can only be seen in that particular c-file (aka compilation unit). So:

file1.c

int gInt1;         // Global variable that can be seen by all c-files

static int gInt2; // Global variable that can be seen only by this c-file

void foo(void)
{
int lInt; // Local variable

...
}

In order to use a global variable from another c-file, you tell the compiler that it exists in some other file. For this you use the extern keyword.

file2.c

extern int gInt1;  // Now gInt1 can be used in this file

void bar(void)
{
int n = gInt1 * (gInt1 + 1);

...
}

You often put the extern declaration into a header file. Like:

file1.h

extern int gInt1;  // Any c-file that includes file1.h can use gInt1

file2.c

#include "file1.h" // Now gInt1 can be used in this file

void bar(void)
{
int n = gInt1 * (gInt1 + 1);

...
}

Regarding initialization

Initializing a global variable is no different from initializing a local variable.

The only difference between global and local variables is when you do not have an initializer. In such cases a local variable will be left uninitialized while global variables will be default initialized (which typically means initialized to zero).

file1.c

int gInt1 = 42;         // Global variable explicit initialized to 42

int gInt2; // Global variable default initialized to 0

void foo(void)
{
int lInt1 = 42; // Local variable explicit initialized to 42

int lInt2; // Local variable uninitialized. Value is ??
...
}

static and external variables

Problem is that in C static can have different meanings. I will try to give an overview of the different situations in the following paragraphs.

If a variable is defined outside a function, it can be used by all functions in the file. Sometimes also called 'global variable'. This means that there is only one instance of this variable for the whole file. Also the name of the variable is stored in the resulting .OBJ file. This latter is important, since if another file also defines a variable with the same name outside a function, the linker assumes that it's the same variable in both cases, and merges them.
To make this extra clear, it's best to add the keyword "extern" to one of the variables. In this case, we say that we declare the variable, instead of defining it. It is an extra signal for the compiler/linker to indicate that we actually want to refer to a global variable defined somewhere else.

If you want to define a global variable, but don't want to make it available to other files, add the keyword static before. The keyword static tells the compiler that the variable name must not be stored in the .OBJ file. This means that two .C files with the following line:

static long MyGlobalVariable;

will each have their own variable. Both variables will be called MyGlobalVariable.

If you define a variable inside a function, it becomes a local variable. It comes into existence if the function is called, and disappears again after the function is finished.
In some situations you want to keep the value of the variable in between function calls. You could do this by using a global variable (instead of a local variable) but then the variable becomes available for all functions in the file, which you don't necessarily want. In that case you can put the keyword static before the variable, like this:

void MyFunction()
{
static long MyLocalVariable = 0;
++MyLocalVariable;
}

The first time the function is called, MyLocalVariable will be 'created' and initialized with the value 0. At the end of the function, the variable is not destroyed, but kept. So the next time you call this function, the value of the variable will be 1, not zero.

In C it really doesn't matter whether you put the variable outside the function (as global variable) or define it as static inside the function. The only difference is where the variable can be accessed.

In C++, things are quite different. If you write this (outside a function):

MyClass MyGlobalVariable;

MyGlobalVariable will be constructed (this is: the constructor will be executed) at the start of the application, before even main is called. However, you don't have real control over the order in which all global variables are constructed.
So if another file contains this:

MyOtherClass MySecondGlobalVariable;

You can't know for sure whether MyGlobalVariable or MySecondGlobalVariable is constructed first. This can give problems if the constructor of one of them relies on the presence (construction) of the other one.

On the other hand, if you define the variable as static inside a function:

void MyFunction()
{
static MyClass MyStaticVariable;
}

Then MyStaticVariable will be constructed the first time the function is called. With this construction, you can write something like this:

MyClass &getMyClass()
{
static MyClass MySelf;
return MySelf;
}

And we have implemented a singleton where we have control on when it is constructed. The first time we need it, it's constructed.

To be honest, this approach is a rather simplistic one, because it may lead to problems in multi-threaded applications. In that case, there are other tricks.

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.

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