包括<atomic>中断 GCC 的转换零诊断,distcc 修复它。(包括最少的例子)



这个问题实际上由两个观察结果组成。

第一:<atomic>的包含使GCC至少在某些情况下不会发出conversion-null诊断信号,否则会发出
例如,考虑文件noerror.cpp:

#include <atomic>
#pragma GCC diagnostic error "-Wconversion-null"
int * foo() {return false;}

这个文件(error.cpp)除了注释掉include:之外是相同的

//#include <atomic>
#pragma GCC diagnostic error "-Wconversion-null"
int * foo() {return false;}

如果我试图编译error.cpp,我会得到一个预期的错误:

$ g++-4.8 -c -std=c++11 error.cpp
error.cpp: In function ‘int* foo()’:
error.cpp:3:21: error: converting ‘false’ to pointer type ‘int*’ [-Werror=conversion-null]
int * foo() {return false;}
^
cc1plus: some warnings being treated as errors

如果我省略了#pragma,改为使用-Werror编译,我会得到相同的结果。这也是意料之中的:根据GCC文档,默认情况下会启用警告。

令我惊讶的是,我可以毫无错误地编译noerror.cpp。即使<atomic>标头通过#pragma GCC diagnostic ignore抑制了警告和错误,我的代码中的显式杂注也应该重新启用它们,但它没有。

顺便说一句,无论是否包括报头,clang++都会出现预期错误:

error: cannot initialize return object of type 'int *' with an rvalue of type 'bool'

第二:使用distcc运行可恢复正常行为
我有多个工作站。如果我试图在它们中的任何一个上进行本地构建,我会遇到上述行为。但是,如果distcc试图在任何远程机器上构建它,那么错误就会正确地发出。(这就是我最初发现这个问题的原因;我们的构建很可能会使distcc回退到本地编译)。事实上,即使我在自己的机器上有distccSSH,也会恢复正确的行为(即错误):

$ DISTCC_HOSTS='localhost' distcc g++-4.8 -c -std=c++11 noerror.cpp # no error
$ DISTCC_HOSTS='@[my_ip_address]' distcc g++-4.8 -c -std=c++11 noerror.cpp
noerror.cpp: In function ‘int* foo()’:
noerror.cpp:3:21: error: converting ‘false’ to pointer type ‘int*’ [-Werror=conversion-null]
cc1plus: some warnings being treated as errors

我不清楚distcc是如何恢复正常行为的。

版本信息:我运行的是Ubuntu3.5.0-46-generic、GCC 4.8.1和distcc 3.1。

摘要

包括<atomic>似乎打破了GCC对conversion-null的诊断。不知怎么的,使用distcc修复了它。我已经搜索过了,但找不到任何类似bug的引用。这个试点错误是一个已知的问题,还是我应该提交GCC错误报告

[编辑:代码片段是我将其作为警告而非错误时的代码片段。粘贴了更正后的版本]

我进一步发现,只有在将编译和预处理组合在一个步骤中时才会发生这种情况。这解释了使用distcc时的行为差异:它预处理本地机器上的所有代码,并远程编译。

尽管@user2485710的评论与此相反,但这并不是飞行员错误或使用了记录不足的功能。这是一个真正的错误,我已经报告过了:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60304

[目前尚未解决,但Harald van Dijk指出,GCC抑制警告是因为它(错误地)认为它在系统标头中。可以使用-Wsystem-headers重新暴露错误/警告。]

相关内容

  • 没有找到相关文章

最新更新