我发现这拒绝编译:
int test_alloc_stack(int size){
if(0) goto error; // same issue whatever conditional is used
int apply[size];
give_values(apply,size);
return 1;
error:
return 0;
}
我得到的错误是:“跳转到具有可变修改类型的标识符范围”。 使用“goto”消除行并跳转到错误可以解决问题。
如果我使用动态分配申请,那么问题也会消失。编译好了:
int test_alloc_heap(int size){
if(0) goto error;
int * apply = calloc(sizeof(int),size);
give_values(apply,size);
free(apply);
return 1;
error : return 0;
}
发生了什么事?
答案 0 :(得分:22)
宣言:
int apply[size];
创建一个可变长度数组。当它超出范围时,编译器必须生成一些代码来清除该数组的分配。我想是跳过这样一个对象的范围是禁止的,因为有些实现可能需要安排一些清理代码需要的初始化,如果你跳进作用域,初始化就会被绕过。
如果更改为动态分配,则初始化和清理将成为您的责任,而不是编译器。
答案 1 :(得分:19)
标准禁止:
C99标准,第6.8.6.1段
<强>约束强>
[...] goto声明应 不要从具有可变性的识别者的范围之外跳出 修改类型到该标识符的范围内。
这正是您goto
正在做的事情,即从apply
范围之外跳到其中。
您可以使用以下解决方法来限制apply
的范围:
if(0) goto error;
{
int apply[size];
give_values(apply,size);
return 1;
}
error:
return 0;
答案 2 :(得分:7)
您的goto
会跳过分配apply
的行(在运行时)。
您可以通过以下四种方式之一解决问题:
1:重写代码,不要使用goto。
2:将apply
的声明移至goto
之前。
3:更改范围,以使error:
超出apply
的范围:
int test_alloc_stack(int size){
if(0) goto error; // same issue whatever conditional is used
{
int apply[size];
give_values(apply,size);
return 1;
}
error:
return 0;
}
4:更改变量声明,以便在编译时确定其大小。