简体   繁体   English

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

[英]C : stack memory, goto and “jump into scope of identifier with variably modified type”,

I found that this refuses to compile : 我发现这拒绝编译:

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;
}

The error I get is : "jump into scope of identifier with variably modified type". 我得到的错误是:“跳入具有可变修改类型的标识符范围”。 Eliminating the line with "goto" and the jump to error solves the issues. 用“ goto”消除该行,并跳转到错误解决了这些问题。

If I use dynamic allocation for apply, then the problem also disappear. 如果我使用动态分配进行申请,那么问题也将消失。 This compiles fine: 这样可以编译:

 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;
}

What is going on ? 到底是怎么回事 ?

The declaration: 声明:

int apply[size];

creates a variable length array. 创建一个可变长度的数组。 When it goes out of scope, the compiler must produce some code that cleans up the allocation for that array. 当超出范围时,编译器必须生成一些代码,以清理该数组的分配。 Jumping into the scope of such an object is forbidden I imagine because some implementations might need to arrange for some initialization that the clean up code would require, and if you jump into the scope the initialization would be bypassed. 我想象禁止进入此类对象的范围,因为某些实现可能需要安排清理代码所需的一些初始化,并且如果您进入该范围,则将绕过初始化。

If you change to a dynamic allocation, the initialization and clean up become your responsibility instead of the compiler's. 如果更改为动态分配,则初始化和清理将由您负责,而不是由编译器负责。

It is forbidden by the standard: 该标准禁止:

C99 standard, paragraph 6.8.6.1 C99标准第6.8.6.1段

Constraints 约束条件

[...] A goto statement shall not jump from outside the scope of an identifier having a variably modified type to inside the scope of that identifier. [...] goto语句不应从类型有所不同的标识符范围外跳到该标识符范围内。

Which is exactly what your goto is doing, namely, jumping from outside the scope of apply to inside it. 您的goto正是在这样做,即从apply范围之外跳到内部。

You can use the following workaround to limit the scope of apply : 您可以使用以下变通办法来限制apply范围:

if(0) goto error;

{
    int apply[size];
    give_values(apply,size);
    return 1;
}

error:
return 0;

Your goto makes you skip the line that allocates apply (at runtime). 您的goto使您跳过分配apply的行(在运行时)。

You can solve the problem in one of four ways: 您可以通过以下四种方法之一解决问题:

1: Rewrite your code so you don't use goto. 1:重写您的代码,以免使用goto。

2: Move the declaration of apply to before the goto . 2:在goto之前移动apply的声明。

3: Change the scope so that error: is outside the scope of 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: Change the variable declaration so its size can be determined at compile-time. 4:更改变量声明,以便可以在编译时确定其大小。

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

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