使用goto跳转到内部或兄弟范围

Spi*_*ike 11 c scope goto

是否允许跳转到内部范围或兄弟范围内的标签?如果是这样,是否允许使用在该范围内声明的变量?

考虑以下代码:

int cond(void);
void use(int);

void foo() 
{
    {
        int y = 2;
        label:
        use(y);
    }

    {
        int z = 3;
        use(z);

        /* jump to sibling scope: */ if(cond()) goto label;
    }

    /* jump to inner scope: */ if(cond()) goto label;
}
Run Code Online (Sandbox Code Playgroud)

这些goto合法吗?

如果是这样,y当我跳转label并保持分配给它的最后一个值(2)时,保证存在?

或者允许编译器假设y在超出范围后不会被使用,这意味着单个内存位置可以用于yz

如果此代码的行为未定义,我如何让GCC发出警告?

ser*_*gej 9

从C99标准(强调我的):

6.2.4对象的存储持续时间

[6]对于具有可变长度数组类型的对象,其生命周期从对象的声明扩展,直到程序的执行离开声明的范围....如果以递归方式输入范围,则每次都会创建该对象的新实例.对象的初始值是不确定的.

6.8.6.1 goto声明

[1] goto语句中的标识符应命名位于封闭函数中某处的标签.甲goto陈述,不能从具有一个标识符的范围之外跳可变类型到该标识符的范围内.

[4] ... goto不允许语句跳过具有可变修改类型的对象的任何声明.

结论

  1. y不是一种可变的修改类型,因此,根据标准,跳跃是合法的.

  2. y保证存在,但跳转跳过initial(y = 2),因此值y不确定的.

  3. 您可以使用-Wjump-misses-initGCC发出如下警告:

    warning: jump skips variable initialization [-Wjump-misses-init]


在C++中,跳转是不合法的,C++不允许跳过初始化y.


alk*_*alk 7

跳转是合法的(在C中,在C++中它们不是).

y保证当我跳到存在label

是.

并保持分配给它的最后一个值(2)?

没有.

C11标准(草案)6.2.4/6:

对于没有可变长度数组类型的此类对象[没有存储类说明符static],其生命周期从entry进入与其关联的块,直到该块的执行以任何方式结束.[...]对象的初始值是不确定的.如果为对象指定了初始化,则每次在执行块时达到声明[...]时执行初始化; 否则,每次达到声明时,该值将变为不确定.

从上面的人会得出结论的为第2和第3次use(y)被调用的值y项" 不确定[d] ",为的初始化y " ".