我和这个人有同样的问题。使用 clang 和 ccache 编译,每次遇到Q_OBJECT时我都会收到此警告:
warning: explicitly assigning value of variable of type 'int' to itself [-Wself-assign]
这只发生在使用 ccache 时,单独使用 clang 编译相同的代码就可以了。
宏扩展似乎也存在类似的问题,建议的解决方案是设置环境变量
CCACHE_CPP2=yes
不幸的是,这似乎不能解决我的问题,或者我做错了。
我试过:
从命令行构建
CCACHE_CPP2=yes ninja
export CCACHE_CPP2=yes ninja
从Qt Creator构建,为"构建环境"添加
CCACHE_CPP2
我还能做些什么来解决这个宏扩展问题吗?我特别不想全局(因为这很糟糕)或本地禁用警告(因为这意味着将所有宏包装在特定于编译器的样板中)。
尝试将 -Wno-self-assign 添加到 CPP 标志中。它应该允许您禁用自分配错误:
CXXFLAGS= $(CXXFLAGS) -Wno-self-assign
或
CPPFLAGS=$(CPPFLAGS) -Wno-self-assign
原谅我没有叮当来测试这个,但我觉得无论如何我都应该提供帮助。在 Marek 的答案的基础上进行扩展,有可能将编译指示放在另一个宏扩展中。这是一个非常丑陋的解决方案,但这样你只需要定义一次宏,而不是在你的代码库中生成编译指示。
#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 进行测试),但是通过在宏中用"clang"替换"GCC"(并使用 -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 上,我必须运行两次预处理器才能工作。无法判断叮当声是否同样必要。
IMO 在全球范围内忽略此警告不是问题。它警告的是虚拟代码,而不是由拼写错误引起的潜在逻辑错误。这就是为什么我投票赞成@MichaelCMS答案。
但是有一种方法可以禁用警告,只有某些代码部分:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-assign"
Q_OBJECT
#pragma clang diagnostic pop
这应该可以解决问题(如果我没有弄乱标志名称),但我不喜欢它,很多样板宏。