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

这些gotos合法吗?

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

或者是允许编译器假定在超出范围之后不会使用y,这意味着单个内存位置可以用于y和z?

如果这段代码的行为是未定义的,那么如何让GCC发出警告呢?

解决方法

从C99标准(强调我的):

6.2.4 Storage durations of objects

[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 The goto statement

[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] … A goto statement is not allowed to jump past any declarations of objects with variably modified types.

结论

> y不是可变的类型,所以根据标准,跳转是合法的.
y保证存在,但是跳转跳过初始化(y = 2),所以y的值是不确定的.
>你可以使用-Wjump-misses-init来让GCC发出如下的警告:

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

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

相关文章

对象的传值与返回说起函数,就不免要谈谈函数的参数和返回值...
从实现装饰者模式中思考C++指针和引用的选择最近在看...
关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自...
那些陌生的C++关键字学过程序语言的人相信对关键字并...
命令行下的树形打印最近在处理代码分析问题时,需要将代码的...
虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特...