C:堆栈内存,转到和“跳转到具有可变修改类型的标识符范围”,
我发现这拒绝编译:
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; }
到底是怎么回事 ?
声明:
int apply[size];
创建一个可变长度数组。 当它超出范围时,编译器必须生成一些代码来清除该数组的分配。 我想是跳过这样一个对象的范围是禁止的,因为某些实现可能需要安排清理代码需要的一些初始化,如果你跳入范围,则会绕过初始化。
如果更改为动态分配,则初始化和清理将成为您的责任,而不是编译器。
标准禁止:
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;
你的goto
让你跳过分配apply
的行(在运行时)。
您可以通过以下四种方式之一解决问题:
1:重写您的代码,这样您就不会使用goto。
2:在goto
之前移动apply
的声明。
3:更改范围,以便error:
超出适用范围:
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:更改变量声明,以便在编译时确定其大小。