goto 产生错误“绕过初始化”

问题描述 投票:0回答:2

既然其他人有兴趣回答和评论这篇文章,你能投票吗?喜欢奉献的人显然不知道如何删除奉献或对回帖进行投票。

我正在尝试在我的项目中使用标签,但是当我使用 goto 跳过一组指令将控制权转移到代码的另一部分时,我收到此错误: 转移控制绕过(某些变量)的初始化 .

这是产生错误的代码:

    goto label1;

    label00:
    int a = 0;//the compiler can't let me skip this line
    int b; // but this line is fine to skip over
    b = 0; //because i initialize it here instead of doing it like the a variable

    label1:
    //other instructions

如您所见,我初始化了两个变量,但其中一个是定义然后初始化的,但另一个是在同一行定义和初始化的。

在同一行定义和初始化的变量 a 跳过时不会产生错误,但另一个会产生错误。

我正在使用VS2019编译此代码。我认为这根本不应该抛出错误,编译器应该给你一个警告,这样你就知道你在这两种情况下都跳过了一些东西

a和b初始化

有什么解决办法吗,比如在设置中禁用某些功能?

我不想在使用标签时声明变量然后初始化它们。

c++ label visual-studio-2019
2个回答
2
投票
我认为这根本不应该引发错误

编译器可以自由拒绝编译格式错误的程序。

有什么办法解决这个问题吗

解决方案:

    不要初始化
  1. a
  2. 在跳转前声明
  3. a
  4. 在标签后声明
  5. a
  6. 不要使用
  7. goto
    (我最喜欢的)。
  8. 通过在标签之前结束的块语句中声明它来限制
  9. a
     的范围。

0
投票
问题中使用的示例变量是

int

,所以问题并不明显。但是,如果您将 
int
 更改为不可
轻易破坏的内容,您可以很容易地注意到为什么这是不允许的。

考虑这段代码:

#include<string> int main() { goto label_bypass; std::string str("gibberish"); label_bypass: return 0; }
当函数即将返回时,它必须销毁所有堆栈变量,包括

str

。通过调用 
str
 的析构函数,它尝试释放 
str
 的字符串缓冲区。然而,由于 
str
 的初始化被绕过,缓冲区从未被分配。缓冲区的指针很可能指向随机地址。分段错误!您可能还希望编译器足够聪明,能够决定在取消堆栈时是否调用析构函数,但如果程序变得足够复杂,这几乎是不可能的。所以c++选择完全禁止跳过初始化。

int b; b = 0;

 的情况一样,由于 
int
 是主类型,因此 
int b
 可以被视为未初始化的声明,而 
b = 0
 是赋值。他们都可以被跳过。

© www.soinside.com 2019 - 2024. All rights reserved.