错误:跳转到标签'foo'越过'bar'的初始化

Pau*_*l R 6 c++ gcc clang icc visual-c++

以下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;
}
Run Code Online (Sandbox Code Playgroud)

克++:

init.cpp:13: error: jump to label ‘clean_up’
init.cpp:4: error:   from here
init.cpp:7: error:   crosses initialization of ‘int i’
Run Code Online (Sandbox Code Playgroud)

铛++:

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;
        ^
Run Code Online (Sandbox Code Playgroud)

ICC:

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

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

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


为了额外的功劳,我也很好奇这个错误背后的简单标量初始化的原理 - 我可以看到为什么跳过一个构造函数可能会有问题,但是int在上面的例子中初始化似乎并不像它可能是一个问题,简单地将定义+初始化拆分为定义+赋值会使错误消失?

Mel*_*ius 2

将警告视为错误的 MSVC 标志是警告编号/we nn

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

有关详细信息,请参阅https://msdn.microsoft.com/en-us/library/thxezb7y.aspx