这个问题实际上包含两个观察结果。
第一:包含使 GCC至少在某些情况下<atomic>
不会发出诊断信息。conversion-null
例如,考虑文件noerror.cpp
:
#include <atomic>
#pragma GCC diagnostic error "-Wconversion-null"
int * foo() {return false;}
error.cpp
除了注释掉包含之外,这个文件 ( ) 是相同的:
//#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 回退到本地编译)。事实上,即使我有distcc
SSH 连接到我自己的机器,也会恢复正确的行为(即错误):
$ 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
设法恢复正确的行为。
版本信息:我正在运行 Ubuntu 3.5.0-46-generic
、GCC 4.8.1 和 distcc 3.1。
概括
包括<atomic>
似乎打破了 GCC 的conversion-null
诊断。不知何故,使用 distcc 修复它。我已经搜索过,但找不到对类似错误的任何引用。这个试点错误是一个已知问题,还是我应该提交一份 GCC 错误报告?
[编辑:代码片段来自我将其设为警告而不是错误时。粘贴更正版本]