C:堆栈内存,转到和"jump into scope of identifier with variably modified type",



我发现这拒绝编译:

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正在做的事情,即从apply范围之外跳到范围之内。

您可以使用以下解决方法来限制apply的范围:

if(0) goto error;
{
    int apply[size];
    give_values(apply,size);
    return 1;
}
error:
return 0;

您的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:更改变量声明,以便在编译时确定其大小。

相关内容

最新更新