简体   繁体   中英

Why does variable declared with static, extern and without it contains differenr values

Consider the following code snippets:

#include <stdio.h>

int a=5;

int main ()
{
    extern int a;
    printf("%d\n",a); //5
}

//---------//

#include <stdio.h>

int a=5;

int main ()
{
    static int a;
    printf("%d\n",a); //0
}

//---------//

#include <stdio.h>

int a=5;

int main ()
{
    int a;
    printf("%d\n",a); //12497123435
}

I don't understand why 5 displayed when a declared with extern specifier? When we declare a with static modifier then a has linkage and a can be denoted an entity from another scope.

When you write extern int a; , you're declaring a variable named a with extern linkage, but you do not define it. Instead a definition must exist elsewhere - usually in a different translation unit. In this case the definition of a is in the same translation unit and the declaration is completely redundant because a is already visible. That said a redundant declaration is not an error, so it behaves the same way as if the declaration did not exist at all. If the definition were in a different translation unit, you'd need the declaration, so the compiler knows that the variable exists at all. In either case the extern declaration does not introduce a new variable and a simply refers to the global variable.

static int a and int a however are definitions and introduce a new variable named a , so the value of the global variable a is no longer relevant.

The difference between static int a and int a is that they have different storage. int a has automatic storage and using an uninitialized variable with automatic storage invokes undefined behavior, which is why you get a "random" value in your case. Variables with static or extern linkage on the other hand are automatically initialized to 0, so that's why you get 0 for your static variable.

Your first example behaves as expected and is perfectly reasonable. Your second two examples are just bugs. In both of them, you create a new variable called a and read its value before setting its value.

i.

int a=5;

int main ()
{
    extern int a;
    printf("%d\n",a); //5
}

The extern int a; promises to the compiler that you will see a definition in a translation unit corresponding to my declaration. In this case, the definition is int a=5; . So the printed value will be 5 .

ii.

int a=5;

int main ()
{
    static int a;
    printf("%d\n",a); //0
}

It declares a variable a inside the scope and static variables will be initialized by zero. So you have 0 . The outer variable a is hidden by the new a .

iii.

int a=5;

int main ()
{
    int a;
    printf("%d\n",a); //12497123435
}

It declares a new a inside the scope which is not initialized and reading its value is undefined behavior. Many times you see a garbage value. The outer variable a is hidden by the new a .

extern int a is only a declaration (ie an announcement) that a variable with name a is defined somewhere else, which in your case refers to the global variable.

static int a defines a variable with static storage duration. Variables of such duration are zero-initialized (statically).

int a (in the function scope) defines a with automatic storage duration. It is uninitialized. Reading its value invoke undefined behavior (UB) — your third example is dangerous, as it invokes UB.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM