考虑这个代码:
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发出警告呢?
解决方法
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. Agoto
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的初始化.