C中的goto语句

kum*_*mar 3 c goto variable-declaration

#include<stdio.h>

int main() 
{
    int i  = 10;

    printf("0 i %d %p\n",i,&i);
    if (i == 10)
        goto f;

    {
        int i = 20;
        printf("1 i %d\n",i);
    }
    {
        int i = 30;
        f:
        printf("2 i %d %p\n",i,&i); //statement X
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

[test]$ ./a.out 

0 i 10 0xbfbeaea8

2 i 134513744 0xbfbeaea4
Run Code Online (Sandbox Code Playgroud)

我很难理解语句X如何工作?当你看到输出它是垃圾.应该说我没有声明?

leg*_*s2k 9

那是因为goto跳过了阴影变量i的初始化.

这是C和C++之间差异的细微差别之一.在严格的C++中,跨越变量初始化是一个错误,而在C中它不是.GCC也证实了这一点,当你使用-std = c11进行编译时,它允许使用std = c ++ 11它会抱怨:跳转到标签'f'越过'int i'的初始化.

来自C99:

goto语句不应从具有可变修改类型的标识符范围之外跳转到该标识符的范围内.

VLA是可变修饰类型.允许在不包含VM类型的范围内跳转.

从C++ 11(强调我的):

从具有自动存储持续时间的变量不在范围内的点跳转到其在范围内的点的程序是不正确的,除非该变量具有标量类型,具有普通默认构造函数的类类型和普通的析构函数,这些类型之一的cv限定版本,或者前面类型之一的数组,并且在没有初始化程序的情况下声明.

  • 我认为声明被跳过是错误的.事实并非如此.变量声明是编译时的事情.goto在运行时跳过初始化为30,因此在打印时它包含垃圾. (2认同)