使用 goto 跳转到内部或同级作用域 [英] Using goto to jump to inner or sibling scope

查看:68
本文介绍了使用 goto 跳转到内部或同级作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it allowed to jump to a label that's inside an inner scope or a sibling scope? If so, is it allowed to use variables declared in that scope?

考虑这个代码:

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;
}

这些goto合法吗?

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

If so, is y guaranteed to exist when I jump to label and to hold the last value assigned to it (2)?

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

Or is the compiler allowed to assume y won't be used after it goes out of scope, which means a single memory location may be used for both y and z?

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

If this code's behavior is undefined, how can I get GCC to emit a warning about it?

推荐答案

来自 C99 标准(重点是我的):

From the C99 standard (emphasis mine):

6.2.4 对象的存储期限

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

[6] For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration. ... If the scope is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate.

6.8.6.1 goto 语句

6.8.6.1 The goto statement

[1] goto 语句中的标识符应命名位于封闭函数中某处的标签.goto 语句不应从具有可变修改类型的标识符的范围外跳转到该标识符的范围内.

[1] 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.

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

[4] ... A goto statement is not allowed to jump past any declarations of objects with variably modified types.

结论

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

  1. y is not a variably modified type, so, according to the standard, the jumps are legal.

y 保证存在,但是跳转会跳过初始化(y = 2),所以 y 的值> 不确定.

y is guaranteed to exist, however, the jumps skip the initialization (y = 2), so the value of y is indeterminate.

您可以使用 -Wjump-misses-init 让 GCC 发出如下警告:

You can use -Wjump-misses-init to get GCC to emit a warning like the following:

警告: 跳转跳过变量初始化[-Wjump-misses-init]

<小时>

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

这篇关于使用 goto 跳转到内部或同级作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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