繁体   English   中英

C:堆栈存储器,goto和“跳转到具有可变修改类型的标识符范围”,

[英]C : stack memory, goto and “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语句不应从类型有所不同的标识符范围外跳到该标识符范围内。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM