【问题标题】:Auto Initialization of local variables局部变量的自动初始化
【发布时间】:2017-01-19 06:52:00
【问题描述】:

我有以下代码sn-p。

int j;
printf("%d",j);

不出所料,我得到了一个垃圾值。

32039491

但是当我在上面的 sn-p 中包含一个循环时,就像

int j;
print("%d",j);
while(j);

我在程序的多次试验中得到以下输出。

0

我一直认为局部变量默认初始化为垃圾值,但看起来变量在使用循环时会自动初始化。

【问题讨论】:

  • 我使用的是 VC++ 6.0 IDE 和编译器,但没有得到不同的结果。
  • 垃圾值按其定义是垃圾。你不能指望它们有一定的价值。
  • 一个 gargabe 值可以是包含 0 的任何值。

标签: c variables scope initialization


【解决方案1】:

它具有不确定的价值。它可以是任何东西。

引用C11§6.7.9

如果具有自动存储持续时间的对象未显式初始化,则其值为 不定。 [...]

自动局部变量,除非显式初始化,否则将包含不确定的值。如果您尝试使用一个变量,而它的值是不确定的,或者

  • 没有占用地址
  • 可以有陷阱表示

使用会导致undefined behavior

【讨论】:

  • 如果 OPs 代码中的变量具有自动存储持续时间(我们无法判断),访问它们是未定义的行为,但不是因为陷阱表示。 See this.
  • @Lundin 谢谢指点先生,更新了我的答案,现在好些了吗?
【解决方案2】:

不出所料,我得到了一个垃圾值。

那么你的期望就是不合理的希望。当您使用未初始化对象的不确定值时,您通常会获得(并且对于您的代码 sn-ps,您确实会获得)未定义的行为。打印垃圾值只是无数种可能的表现形式之一。

我一直认为局部变量默认初始化为垃圾值,但看起来变量在使用循环时会自动初始化。

你想错了,你也得出了错误的结论。您的两个代码 sn-ps 在单独运行时都表现出未定义的行为。您不能安全地依赖任何特定的结果。

【讨论】:

  • 您无法知道这是未定义的行为,因为我们无法根据 OPs 代码判断范围。同样,您不能假设 OP 正在使用具有陷阱表示的系统。因此这可能是不正确的:“当您使用未初始化对象的不确定值时,您会得到未定义的行为”。 See this.
  • @Lundin,感谢您指出这一点。我已经对答案进行了一些限定,以允许自己拥有足够的空间。任何对我这样做的原因感兴趣的人(即行为未定义时的详细信息)都可以点击您提供的链接。
猜你喜欢
  • 2021-03-17
  • 2016-09-07
  • 2012-10-03
  • 1970-01-01
  • 2017-05-14
  • 2016-01-14
  • 1970-01-01
  • 2018-09-23
  • 1970-01-01
相关资源
最近更新 更多