1

这个问题实际上包含两个观察结果。

第一:包含使 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 回退到本地编译)。事实上,即使我有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设法恢复正确的行为。

版本信息:我正在运行 Ubuntu 3.5.0-46-generic、GCC 4.8.1 和 distcc 3.1。

概括

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

[编辑:代码片段来自我将其设为警告而不是错误时。粘贴更正版本]

4

1 回答 1

1

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

尽管@user2485710 发表了相反的评论,但这不是飞行员错误或使用记录不充分的功能的情况。这是一个真正的错误,我已经这样报告了它:

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

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

于 2014-02-25T18:01:31.723 回答