C:堆栈内存,转到和"跳转到具有可变修改类型的标识符范围",

 金子祺_475 发布于 2023-02-09 15:06

我发现这拒绝编译:

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

到底是怎么回事 ?

3 个回答
  • 标准是禁止的:

    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;
    

    2023-02-09 15:07 回答
  • 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:更改变量声明,以便在编译时确定其大小.

    2023-02-09 15:08 回答
  • 声明:

    int apply[size];
    

    创建一个可变长度数组.当它超出范围时,编译器必须生成一些代码来清除该数组的分配.我想是跳过这样一个对象的范围是禁止的,因为有些实现可能需要安排一些清理代码需要的初始化,如果你跳入范围,初始化将被绕过.

    如果更改为动态分配,初始化和清理将成为您的责任,而不是编译器.

    2023-02-09 15:10 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有