【问题标题】:error: jump to label 'foo' crosses initialization of 'bar'错误:跳转到标签“foo”与“bar”的初始化交叉
【发布时间】:2015-10-09 09:59:38
【问题描述】:

以下 C++ 示例无法使用 gcc 或 clang 编译,但仅使用 ICC 生成警告,而使用 MSVC 则根本没有:

int main(int argc, char *argv[])
{
    if (argc < 2)
        goto clean_up;

#if 1   // FAIL
    int i = 0;
#elif 0 // workaround - OK
    {
        int i = 0;
    }
#else   // workaround - OK
    int i;
    i = 0;
#endif

clean_up:
    return 0;
}

g++:

init.cpp:13: error: jump to label ‘clean_up’
init.cpp:4: error:   from here
init.cpp:7: error:   crosses initialization of ‘int i’

叮当++:

init.cpp:4:9: error: cannot jump from this goto statement to its label
        goto clean_up;
        ^
init.cpp:7:9: note: jump bypasses variable initialization
    int i = 0;
        ^

国际商会:

init.cpp(4): warning #589: transfer of control bypasses initialization of:
            variable "i" (declared at line 7)
          goto clean_up;
          ^

我了解错误的原因,对于像这样的简单示例,它很容易解决(我在上面的示例中包含了几个可能的解决方法),但我正在处理一个大跨平台遗留代码库,其中包含使用类似 goto 构造的错误处理宏。使用 MSVC 或 ICC 的其他开发人员不断引入内联初始化,这随后导致 gcc 或 clang 构建错误(当然,他们只是忽略了使用 MSVC/ICC 收到的警告)。

所以我需要找到一种方法来 (a) 使此类情况导致 ICC/MSVC 上的错误或 (b) 使用 gcc/clang 将它们减少为警告。我用 gcc 尝试了-fpermissive,但这似乎没有帮助。


为了获得额外的荣誉,我也很好奇这个错误背后的基本原理是简单的标量初始化 - 我可以明白为什么跳过 constructor 可能有问题,但是像上面的例子一样初始化 int似乎这永远不会成为问题,只需将定义+初始化拆分为定义+分配即可使错误消失?

【问题讨论】:

  • 开发人员也应该修复他们的编译器警告,而不仅仅是错误。
  • @Melebius:我知道 - 我一直在敲打这个特殊的鼓有一段时间了,但似乎需要一个巨大的文化转变才能让每个人都参与其中。
  • 如果你用大括号 { int i = 0 } 包围定义,它会编译好的,但我猜这不是一个解决方案?您只需要知道哪些编译器标志可以使其构建?
  • @VictorPolevoy:是的,正如我上面提到的,对于这样一个简单的例子来说,修复它是相当容易的,但是对于一个有很多类似情况的大型代码库,它就会成为一个反复出现的问题我正在寻找一个永久的解决方案,而不是继续解决它。
  • @PaulR /we 是为 MSVC 做的。 msdn.microsoft.com/en-us/library/thxezb7y.aspx

标签: c++ visual-c++ gcc clang icc


【解决方案1】:

将警告视为错误的 MSVC 标志是 /we n,其中 n 是警告的编号。

例如,/we4326 将警告编号 C4326 标记为错误。

详情请见https://msdn.microsoft.com/en-us/library/thxezb7y.aspx

【讨论】:

  • 关闭 - 看起来C2362 将是适当的警告/错误,但cl 不会生成此消息,除非您使用/Za 似乎,在这种情况下无论如何它都是错误。不幸的是,使用/Za 不是一种选择,因为它会破坏很多其他的东西。嗯...
  • /Za 似乎禁用了 C++ 标准的 Microsoft 扩展。 msdn.microsoft.com/en-us/library/0k0w269d.aspx你必须决定是使用微软扩展,还是使用 GCC 编译...
  • 是的,不幸的是/Za 破坏了我们现有的许多代码(与所有其他编译器一起编译的代码),所以它不是一个选项。这是遗留代码库最令人头疼的问题之一——你不能“只修复”事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-09
  • 2012-05-10
  • 1970-01-01
  • 2019-04-11
相关资源
最近更新 更多