【问题标题】:Default values of uninitialized local variables in CC中未初始化的局部变量的默认值
【发布时间】:2018-06-30 17:29:20
【问题描述】:

我试图了解 C 中变量的声明和定义。我在学校的学习资料中说,全局未初始化的变量被赋值为 0,而未初始化的局部变量未赋值,并且具有该内存地址中存在的值。

但是,我尝试了以下非常简单的程序:

#include <stdio.h>

void something(){

    int third;
    int fourth;

    printf("third: %d\n", third);
    printf("fourth: %d\n", fourth);
}

int main(){
    int first;
    int second;

    printf("first: %d\n",first);
    printf("second: %d\n",second);
    something();
    return 0;
}

输出如下:

first: 382501330
second: 32766
third: 0
fourth: 0

第二次运行:

first: 235426258
second: 32766
third: 0
fourth: 0

观察:

  • 变量“first”似乎每次都按预期分配一个随机数

  • 变量“秒”每次都被分配相同的数字(32766),为什么?

  • 为什么将变量“第三”和“第四”赋值为零,因为它们是局部变量,而不是全局变量?

【问题讨论】:

  • 0 和 235426258 是一样随机的 - 在可能的位模式中只有一个。

标签: c variables initialization


【解决方案1】:

您正在访问可能已声明为 register 的未初始化本地变量。 那是 undefined 行为。您的程序不再有意义。

如果你通过添加一些 &amp; 运算符来修复它(这样本地人就不能再被声明为 register)

#include <stdio.h>

void something(){

    int third;
    int fourth;

    printf("third: %d\n", *&third);
    printf("fourth: %d\n", *&fourth);
}

int main(){
    int first;
    int second;

    printf("first: %d\n", *&first);
    printf("second: %d\n", *&second);
    something();
    return 0;
}

那么就 C 而言,这些值将是未指定的。你会得到什么取决于你的环境 以及在调用 main 之前,主调用 libc 例程留在堆栈中的内容。

【讨论】:

  • 虽然我个人同意您的解释,但编译器作者要么有不同的解释,要么在将未初始化内存视为导致未指定行为而不是未定义行为时无法帮助编写有错误的编译器。我多年前写了这篇博文:blog.frama-c.com/index.php?post/2013/03/13/…。博文中的示例不再编译为显示 indeterminate-access-as-UB,但仍然只需要花几分钟的时间为最近的编译器编写示例:godbolt.org/g/NYjb2e
  • 感谢您对链接的评论。比我的回答更有价值。 (虽然对于新手来说,我的回答可能就足够了。)信任编译器处理标准的极端情况绝对不是我在被烧了几次之后的建议......好吧,至少 gcc 似乎做对了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 2013-01-17
  • 2012-10-03
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多