【问题标题】:Block level variable scope and lifeline while using a pointer reference使用指针引用时的块级变量范围和生命线
【发布时间】:2016-05-17 12:01:01
【问题描述】:

以下是产生两种不同输出的最简单代码,

  1. 10(Turbo C 版本 3.0)
  2. 0(在线编译器ideone

代码

#include<stdio.h>
int main(){
   int *j;
   {
       int i = 10;
       j = &i;
   }
   printf("%d",*j);
}

这是另一个question on SO 所说的未定义行为的一部分吗?

根据引用的问题,printf 仅产生输出 10 因为没有其他程序/系统覆盖相同 一段记忆。

【问题讨论】:

  • 你为什么使用旧的编译器 Turbo C?那个版本很老了,会产生与ideone后面使用的更现代的不同的结果吗?不仅如此,一个是89标准的,后来的版本是99标准的。
  • @t0mm13b - 虽然我同意鼓励使用更现代的编译器,但该代码会在所有 C 标准版本中产生未定义的行为。只有当行为在一个版本的 C 标准中未定义,而在另一个版本中定义良好时,编译器的年龄才有意义——这里不是这种情况。
  • 在实践中,许多编译器会在函数入口处为范围内变量分配存储空间,并在函数退出时释放它,所以即使i在循环结束时超出范围,存储空间也是仍然分配给它。但是,该行为保证,不应依赖。您的代码中的行为确实是未定义的。

标签: c pointers scope


【解决方案1】:

是的,您链接到的那个问题的答案是正确的。结果是未定义的行为。在所有版本的 C 标准中。

变量i 不再存在,就您的程序而言,在包含它的块的末尾。

j 的值因此是一个已经不复存在的东西的地址。因此,评估 *j 会产生未定义的行为。

未定义行为的一个可能症状是编译器之间的输出不同。还有许多其他可能的症状,因为正式而言,当行为未定义时,任何事情都可以发生。

【讨论】:

  • 我不同意,这取决于 Turbo C 3 所反映的 ANSI C 89 标准与基于范围规则的 ANSI C 99 标准。
  • 作用域规则(关于在{} 的基本块中定义的变量)没有改变。
  • 另见answer,见this 6.2.4 对象存储持续时间部分。
  • @t0mm13b 我在任何一个链接中都没有看到任何表明i 仍在其定义的块之外的范围内。
猜你喜欢
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 2013-11-25
  • 2019-12-20
  • 2020-09-10
  • 2018-07-17
  • 2013-04-05
  • 2014-01-15
相关资源
最近更新 更多