使用 ccache / clang 编译 Qt 代码时避免多余的警告
Posted
技术标签:
【中文标题】使用 ccache / clang 编译 Qt 代码时避免多余的警告【英文标题】:Avoid superfluous warnings when compiling Qt code with ccache / clang 【发布时间】:2015-01-27 09:20:04 【问题描述】:我遇到了与this guy 相同的问题。 使用 clang 和 ccache 编译时,每次遇到 Q_OBJECT 时都会收到此警告:
warning: explicitly assigning value of variable of type 'int' to itself [-Wself-assign]
这仅在使用 ccache 时发生,单独使用 clang 编译相同的代码可以正常工作。
似乎有一个similar issue with macro expansions,建议的解决方案是设置环境变量
CCACHE_CPP2=yes
不幸的是,这似乎无法解决我的问题,或者我做错了。
我试过了:
从命令行构建
CCACHE_CPP2=yes ninja
export CCACHE_CPP2=yes
ninja
从 Qt Creator 构建,将 CCACHE_CPP2
添加到“构建环境”
我还能做些什么来解决这个宏扩展问题吗?我特别不想在全局(因为这很糟糕)或本地(因为这意味着将所有宏包装在特定于编译器的样板文件中)禁用警告。
【问题讨论】:
【参考方案1】:尝试将 -Wno-self-assign 添加到 CPP 标志。它应该允许您禁用自分配错误:
CXXFLAGS= $(CXXFLAGS) -Wno-self-assign
或
CPPFLAGS=$(CPPFLAGS) -Wno-self-assign
【讨论】:
但我仍然希望为我的代码的其他部分启用该警告... 我不知道一种简单快捷的方法来解决这个问题。你可以改变你的makefile来编译一些带有这个标志的单元和一些没有这个标志的单元,但是它会被分配工作并且你仍然会在带有Qt代码和其他代码的单元上遇到同样的问题。【参考方案2】:请原谅我没有用 clang 进行测试,但我觉得无论如何我都应该提供帮助。扩展 Marek 的答案,有可能将 pragma 放在另一个宏扩展中。这是一个非常丑陋的解决方案,但这样您只需要定义一次宏,而不是在整个代码库中生成 pragma。
#define WARN int&x = x;
#define NO_WARN _Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wuninitialized\"") \
WARN \
_Pragma("GCC diagnostic pop")
int main()
NO_WARN
如您所见,我使用 gcc 对其进行了测试(我现在无法使用 clang 进行测试),但是通过在宏中将“GCC”替换为“clang”(并使用 -Wself_assign)在 clang 中应该可以正常工作)。应用于您的问题(伪代码):
#ifdef clang
#define MY_Q_OBJECT _Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wself-assign\"") \
Q_OBJECT \
_Pragma("clang diagnostic pop")
#else
#define MY_Q_OBJECT Q_OBJECT
#endif
class A
MY_Q_OBJECT // Unfortunately you still need to replace Q_OBJECT on your classes
另一个丑陋的缺点是,至少在 gcc 上,我必须运行预处理器两次才能使其工作。不知道clang是否有必要这样做。
【讨论】:
作为附录,请注意,如果不取消警告,可能根本无法解决此问题。这不是一个简单的配置问题,也可能是一个错误。除非我错了,否则您能做的最好的事情就是按照 Michael 和 Marek 的建议提交错误报告并取消警告。【参考方案3】:IMO 在全球范围内忽略此警告不是问题。它警告虚拟代码,而不是由拼写错误引起的潜在逻辑错误。这就是我投票支持@MichaelCMS 答案的原因。
不过有办法disable warning only is some section of code:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-assign"
Q_OBJECT
#pragma clang diagnostic pop
这应该可以解决问题(如果我没有弄乱标志名的话),但我不喜欢它,太多样板宏。
【讨论】:
抱歉,我对任何类型的禁用警告都不满意,因为 a) 不能解决根本问题,例如如果我后来发现宏扩展包含另一个警告并且 b) 我正在尝试编写可移植代码,所以添加这种 pragma 很快就会变得混乱,例如我很确定我需要将 clang pragma 包装在 ifdef 中,以便 msvc 忽略它等。 有一个开关-Weverything
可以用来禁用所有警告。以上是关于使用 ccache / clang 编译 Qt 代码时避免多余的警告的主要内容,如果未能解决你的问题,请参考以下文章
在 Windows 上使用 Qt Creator 设置 ccache
在 MacOS 上使用 gcc-8 而不是 clang 编译 Qt5
Qt 5.1 for OSX 安装只包含 clang_64 目录,如何使用 macports gcc 编译?
如何在 Qt creator 中更改/配置所需的编译器?即在 MSVC/Mingw 或 g++/clang++ 之间切换