简体   繁体   English

局部变量在C中初始化为零

[英]local variable initialized to zero in C

I thought that the local variable in C is not initialized. 我认为C中的局部变量没有初始化。 But when I compiled this code with gcc. 但是当我用gcc编译这段代码时。

void f() {
    static int s;
    int n;

    printf("static s = %d\n", s++);
    printf("local  n = %d\n", n++);

    f();
}

main() {
    f();
}

And run this code, the partial result is: 并运行此代码,部分结果是:

static s = 0
local  n = 0
static s = 1
local  n = 0
static s = 2
local  n = 0
static s = 3
local  n = 0
static s = 4
local  n = 0
static s = 5
local  n = 0
...
static s = 261974
local  n = 0
static s = 261975
local  n = 0
static s = 261976
local  n = 0
static s = 261977
local  n = 0
static s = 261978
local  n = 0
static s = 261979
local  n = 0
static s = 261980
local  n = 0
static s = 261981
local  n = 0
Segmentation fault: 11

Could anyone please explain this? 有人可以解释一下吗? Or refer to a standard reference that C won't init local vars? 或者参考C不会初始化本地变量的标准参考?

ISO/IEC 9899:TC3 WG14/N1256 (C99 standard) section 6.7.8 clause 10: ISO / IEC 9899:TC3 WG14 / N1256 (C99标准)第6.7.8条第10款:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. 如果未显式初始化具有自动存储持续时间的对象,则其值不确定。

If an object that has static storage duration is not initialized explicitly, then: 如果未显式初始化具有静态存储持续时间的对象,则:

  • if it has pointer type, it is initialized to a null pointer; 如果它有指针类型,则将其初始化为空指针;
  • if it has arithmetic type, it is initialized to (positive or unsigned) zero; 如果它有算术类型,则初始化为(正或无符号)零;
  • if it is an aggregate, every member is initialized (recursively) according to these rules; 如果它是一个聚合,则根据这些规则初始化(递归)每个成员;
  • if it is a union, the first named member is initialized (recursively) according to these rules. 如果它是一个联合,则根据这些规则初始化(递归)第一个命名成员。

Your variable fits the first category. 您的变量适合第一类。 Indeterminate means it can be anything (including 0). 不确定意味着它可以是任何东西(包括0)。 Just because it is zero in the tests you have performed, does not mean it will always be or that you can rely on that behaivour. 仅仅因为它在您执行的测试中为零,并不意味着它总是或者您可以依赖于该行为。 The behaivour might change even with the same compiler depending on the compilation options and optimization level. 即使使用相同的编译器,行为也可能会发生变化,具体取决于编译选项和优化级别。

In my experience, it might or might not be initialized to 0 depending on the compiler and the flags used during compile. 根据我的经验,它可能会也可能不会被初始化为0,具体取决于编译器和编译期间使用的标志。

Local non- static variables are not initialized -- which typically means they contain garbage. 本地非static变量未初始化 - 这通常意味着它们包含垃圾。

0 is just as valid a garbage value as any other. 0与任何其他垃圾值一样有效。 But the initial value could just as easily have been 42 or -12345 . 但初始值可能很容易就是42-12345

Just don't do that. 只是不要这样做。 You need to ensure that you don't read the value of any variable unless it's been initialized. 除非已初始化,否则您需要确保不读取任何变量的值。 Reading an uninitialized variable has undefined behavior, which means that the possible behavior is not limited to printing some arbitrary value. 读取未初始化的变量具有未定义的行为,这意味着可能的行为不仅限于打印某些任意值。

A good way to do to do that is to use an explicit initializer: 一个好的方法是使用显式初始化器:

int n = 0;

(Incidentally, you're missing the required #include <stdio.h> , and the correct declaration for main is int main(void) .) (顺便说一句,你缺少必需的#include <stdio.h> ,而main的正确声明是int main(void) 。)

What you're writing exhibits undefined behavior (and I assume gets you a scolding from your compiler). 您正在撰写的内容展示未定义的行为(我假设您从编译器中获得了责任)。 The fact that this compiler produced a program with this output today doesn't particularly mean anything. 今天这个编译器使用此输出生成程序的事实并不特别重要。 The compiler may just be setting all stack memory to zero. 编译器可能只是将所有堆栈内存设置为零。 Or the stack may be advancing through previously zeroed-memory. 或者堆栈可能正在通过先前的归零内存前进。 Or the stack is staying exactly where it is (the compiler couldn't "unroll" your main, after all) and the location of n happened to be a zero word. 或者堆栈正好停留在原来的位置(毕竟编译器无法“展开”你的主程序)并且n的位置恰好是一个零字。 Today. 今天。

If the variable is initialized inside a function it is not initialized automatically. 如果变量在函数内初始化,则不会自动初始化。 When it's declared outside any function, it's initialized with 0. 当它在任何函数之外声明时,它的初始化为0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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