【发布时间】:2016-12-14 23:32:09
【问题描述】:
我正在尝试运行以下 C 代码
#include <stdio.h>
void myFunc() {
static int a;
int b;
a++;
b = b + 2;
printf("a:%d, b:%d\n",a,b);
}
int main(void) {
myFunc();
myFunc();
return 0;
}
我在 ubuntu 上使用 gcc 版本 5.4.0 20160609 编译时得到的结果是
a:1, b:2
a:2, b:4
我知道 a 是静态的,将被零初始化,但似乎非静态 b 也被零初始化。此外,看起来 b 实际上正在被转换为静态变量,因为它的值会在第二次调用 myFunc 时保留。
我假设这与我的编译器/操作系统有关,因为使用 codepad 在线编译(使用 gcc 4.1.2)给出了
a:1, b:2
a:2, b:2
虽然出于某种原因仍将 b 初始化为零,但不会为后续调用 myFunc 保留 b 的值。
1) 为什么非静态变量被零初始化?我是不是一直很幸运编译器为它分配了一个被归零的内存块?
2) 为什么 gcc 似乎将 b 转换为 gcc 4 中的静态变量而不是 gcc 5?
编辑:
为了更好地说明这个问题,如果我再添加 6 个对 myFunc 的调用,结果输出是:
a:1, b:2
a:2, b:4
a:3, b:6
a:4, b:8
a:5, b:10
a:6, b:12
a:7, b:14
a:8, b:16
【问题讨论】:
-
未定义行为未定义...
-
尝试在对
myFunc()的两次调用之间添加另一个(不同的)函数并在该函数中创建新变量...看看会发生什么。但是,就像@John3136 所说... -
@Al Kenny:您如何区分真正的零初始化变量和恰好具有垃圾值 0 的垃圾变量?以及如何区分在调用(静态)之间真正保留其值的变量和恰好偶然匹配其先前值的垃圾变量?
-
"为什么非静态变量被零初始化?"这是不确定的。编译器看到类似
int b; b = b + 2; printf("b:%d\n",b);的代码,可以将其替换为puts("b:2"):或destroy_hard_drive()。两者都可以,因为它是 未定义的行为。 -
内存位置在栈上。由于您是从同一个父函数调用它们,因此每次都使用相同的堆栈内存,并且在调用之间不会覆盖它。
标签: c variables gcc static non-static