C 如果未初始化,自动变量是否具有静态寿命?

C 如果未初始化,自动变量是否具有静态寿命?,c,static,scope,initialization,c99,C,Static,Scope,Initialization,C99,我很好地理解了静态局部变量的概念:全局寿命,局部范围。类似地,我理解当程序流进入和离开变量的上下文时,自动变量会自动分配/释放 #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");

我很好地理解了静态局部变量的概念:全局寿命,局部范围。类似地,我理解当程序流进入和离开变量的上下文时,自动变量会自动分配/释放

#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;
}
让我困惑的是变量在未初始化时的行为:

#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;
}
因此,静态变量的行为与预期一致——获得默认值
0
,并在函数调用中保持不变;但是自动变量似乎也会持续存在——尽管它持有一个垃圾值,但它在每次调用中都会递增


发生这种情况是因为C标准中未定义行为,还是标准中有一套规则解释了这一点?

C标准说,对象的寿命是保证其存储的时间(参见ISO/IEC 9899:TC3的6.2.4)。静态变量和全局变量的生命周期贯穿于整个程序,因此标准保证了上述行为。这些值在程序启动前初始化。对于automatic,对象的地址是恒定的,但只有在其生命周期内才能得到保证。所以,尽管bar在多次函数调用中似乎保持活动状态,但您不能保证它。 这也是为什么你应该总是初始化你的变量,在你使用它之前你永远不可能知道哪个变量在同一个地方

我稍微调整了程序,以同时打印静态变量和局部变量的地址:

#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;
}

这表明在我的机器上,每次调用时,静态
foo
和自动
bar
都位于相同的地址,但这是巧合,C标准不能保证
bar
始终位于相同的地址。

在我看来很像未定义的行为。在test_var函数周围再添加一些变量和函数调用,“fun”可能会随之而来。这是未定义的行为。这可能是因为变量
bar
总是放在同一个位置,并且在调用之间不会被覆盖。我几乎100%肯定这是一个重复的问题。因此,它似乎持续存在的原因可能是因为我的代码太过简单,以至于内存永远不会被覆盖?@VilhelmGray非常可能。如果你在循环体中调用另一个函数,并且在循环体中有两个参数,那么它就有可能重写“C++ >代码>代码的位置。静态变量的值,但在首次使用之前。@ C++的问题VILHELM Gray,C++中的OOP可能有所不同。我说得太快,忽略了语言。
Foo Bar
--- ---
 0   2
 1   3
 2   4
 3   5
 4   6
 5   7
 6   8
 7   9
 8   10
 9   11
#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;
}
Foo Bar
--- ---
 0   33616  0x1067c  0xbee894fc
 1   33617  0x1067c  0xbee894fc
 2   33618  0x1067c  0xbee894fc