【发布时间】: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