GOTO之前局部变量 [英] GOTO before local variable

查看:498
本文介绍了GOTO之前局部变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

执行以下操作code的一块构成不确定的行为,因为我的变量声明前跳,并通过指针使用它吗?如果是这样,是否有标准之间的差异?

INT的main(){
  为int * p值= 0;
LABEL1:
  如果(P){
    的printf(%d个\\ N,* P);
    返回0;
  }
  INT I = 999;
  P =&放;我;
  转到LABEL1;
  返回-1;
}


解决方案

有在你的程序中没有未定义的行为。

转到语句有两个限制:


  

(C11,6.8.6.1p1),在goto语句的标识符命名应设在封闭函数某处的一​​个标签。goto语句,不得由具有可变类型里面的一个标识符的范围之内跳该标识符的范围。


,你是不是违反了,也没有其他应要求之外的限制。

请注意,这是相同的(在这个意义上有没有额外的要求)的C99和C90。当然,在C90,该计划将不会因为宣言和声明的组合是有效的。

关于在转到语句后访问 I 对象的生命周期,C表示(见我的重点,该在下面的段落复制其他句子将是一个更靠谱的程序有趣):


  

(C11,6.2.4p6)的对于这样一个对象,该对象不具有可变长度数组类型,其寿命从进入与它直到该块的执行相关联的块延伸以任何方式结束 [...]如果递归输入的块,则该对象的一个​​新实例,每次创建。[...]如果对象被指定了一个初始化,则在每次进行的声明或在块的执行达到复合文字;否则,该值变得不确定每次达到声明时


这意味着, *读取P I 还活着;没有对象在其生存的外部访问。

Does the following piece of code constitute undefined behaviour, since I am jumping before the variable declaration and using it via a pointer? If so, are there differences between the standards?

int main() {
  int *p = 0;
label1: 
  if (p) {
    printf("%d\n", *p);
    return 0;
  }
  int i = 999;
  p = &i;
  goto label1;
  return -1;
}

解决方案

There is no undefined behavior in your program.

goto statement has two constraints:

(c11, 6.8.6.1p1) "The identifier in a goto statement shall name a label located somewhere in the enclosing function. A goto statement shall not jump from outside the scope of an identifier having a variably modified type to inside the scope of that identifier."

that you are not violating and there is no other shall requirements outside constraints.

Note that it is the same (in the sense there are no extra requirements) in c99 and c90. Of course in c90, the program would not be valid because of the mix of declaration and statements.

Regarding the lifetime of i object when accessed after the goto statement, C says (see my emphasis, the other copied sentences in the following paragraph would be interesting for a more tricky program):

(c11, 6.2.4p6) "For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. [...] If the block is entered recursively, a new instance of the object is created each time. [...] If an initialization is specified for the object, it is performed each time the declaration or compound literal is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached."

That means, i is still alive when *p is read; no object is accessed outside its lifetime.

这篇关于GOTO之前局部变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆