简体   繁体   中英

Automatic variable has static lifespan if not initialized?

I have the concept of static local variables down pretty well: global lifespan , local scope . Similarly, I understand automatic variables are allocated/deallocated automatically when program flow enters and leaves the variable's context.

#include <stdio.h>

void test_var(void){
    static unsigned foo = 0;
    unsigned bar = 0;
    printf(" %u   %u\n", foo++, bar++);
}

int main(void){
    printf("Foo Bar\n");
    printf("--- ---\n");
    for(unsigned x = 0; x < 10; x++){
        test_var();
    }

    return 0;
}

As such, the previous example behaves as expected and prints the following output:

Foo Bar
--- ---
 0   0
 1   0
 2   0
 3   0
 4   0
 5   0
 6   0
 7   0
 8   0
 9   0

What confuses me is how the variables behave when not initialized:

#include <stdio.h>

void test_var(void){
    static unsigned foo;    /* not initialized */
    unsigned bar;           /* not initialized */
    printf(" %u   %u\n", foo++, bar++);
}

int main(void){
    printf("Foo Bar\n");
    printf("--- ---\n");
    for(unsigned x = 0; x < 3; x++){
        test_var();
    }

    return 0;
}

Output:

Foo Bar
--- ---
 0   2
 1   3
 2   4
 3   5
 4   6
 5   7
 6   8
 7   9
 8   10
 9   11

So the static variable behaves as expected -- getting a default value of 0 and persisting through the function calls; but the automatic variable seems to persist as well -- although holding a garbage value, it increments in each call.

Is this occurring because the behavior is undefined in the C standard , or is there a set of rules in the standard that explain this?

The C standard says that the lifetime of an object is the time that storage is guaranteed for it ( see eg 6.2.4 of the ISO/IEC 9899:TC3 ). The lifetime of static and global variables is throughout the program and for this the above behavior is guaranteed by the standard. These values are initialized before program start-up. For automatic also objects are at a constant address but only guaranteed through out their life time. So although bar appears to remain alive over multiple function calls, you can't guarantee it. This is also why you should always initialize your variables, you can never know which variable was at the same spot before you use it.

I slightly adapted the program to also print the address of both the static and local variable:

#include <stdio.h>

void test_var(void){
    static unsigned foo;    /* not initialized */
    unsigned bar;           /* not initialized */
    printf(" %u   %u\t%p\t %p\n", foo++, bar++, &foo, &bar);

}

int main() {
    printf("Foo Bar\n");
    printf("--- ---\n");
    for(unsigned x = 0; x < 3; x++){
        test_var();
    }

    return 0;
}

This yielded the following output on my computer:

Foo Bar
--- ---
 0   33616  0x1067c  0xbee894fc
 1   33617  0x1067c  0xbee894fc
 2   33618  0x1067c  0xbee894fc

This shows that on my machine both the static foo and the automatic bar were at the same respective address for each call, but that is coincidental and the C standard doesn't guarantee that bar will always be at the same address.

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