使用ccache / clang编译Qt代码时避免多余的警告

时间:2021-06-26 16:56:23

I am having the same problem as this guy. Compiling with clang and ccache I get this warning everytime it encounters a Q_OBJECT:

我和这个人有同样的问题。使用clang和ccache编译时,每次遇到Q_OBJECT时,我都会得到这个警告:

warning: explicitly assigning value of variable of type 'int' to itself [-Wself-assign]

This only happens when using ccache, compiling the same code with clang alone works fine.

只有在使用ccache时才会发生这种情况,使用clang编译相同的代码可以正常工作。

There seems to be a similar issue with macro expansions where the suggested solution is to set the environment variable

宏观扩展似乎也有类似的问题,建议的解决方案是设置环境变量

CCACHE_CPP2=yes

Unfortunately, this does not seems to fix my issue, or maybe I'm doing it wrong.

不幸的是,这似乎不能解决我的问题,或者我做错了。

I have tried:

我有尝试:

  • Building from command line with

    从命令行开始构建

    • CCACHE_CPP2=yes ninja

      CCACHE_CPP2 = yes忍者

    • export CCACHE_CPP2=yes ninja

      出口CCACHE_CPP2 = yes忍者

  • Building from Qt Creator, adding CCACHE_CPP2 to "Build Environment"

    从Qt创建者构建,将CCACHE_CPP2添加到“构建环境”

Is there anything else I can do to fix this macro expansion issue? I specifically do not want to disable warnings globally (because that's bad) or locally (because that means wrapping all macros in compiler-specific boilerplate).

我还能做些什么来解决这个宏观扩张问题?我特别不希望在全局(因为这很糟糕)或局部(因为这意味着在特定于编译器的样板中包装所有宏)禁用警告。

3 个解决方案

#1


3  

Try adding -Wno-self-assign to the CPP flags . It should allow you to disable self-assign errors :

尝试向CPP标志添加-Wno-self-assign。它应该允许您禁用自分配错误:

CXXFLAGS= $(CXXFLAGS) -Wno-self-assign 

or

CPPFLAGS=$(CPPFLAGS) -Wno-self-assign

#2


3  

Forgive me for not having clang to test this with, but I felt I should help anyway. Expanding on Marek's answer, there's the possibility of placing the pragma inside another macro expansion. It's a very ugly solution, but that way you only need to define the macro once, instead of spawning pragmas all over your code base.

请原谅我没有使用clang来测试它,但是我觉得无论如何我都应该提供帮助。根据马雷克的答案,有可能把实用主义置于另一个宏观扩张之中。这是一个非常糟糕的解决方案,但是这样您只需要定义一次宏,而不需要在代码库中到处生成实用程序。

#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
}

As you can see, I tested it with gcc(I have no means of testing with clang right now), but that should work fine in clang by substituting "GCC" with "clang" inside the macro(and using -Wself_assign). Applying to your problem(pseudocode):

如您所见,我使用gcc来测试它(我现在没有用clang进行测试的方法),但是如果在clang中使用宏(并使用-Wself_assign)将“gcc”替换为“clang”,那么在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
}

Another ugly downside is that, at least on gcc, I had to run the preprocessor twice for it to work. Can't tell if the same is necessary for clang.

另一个糟糕的缺点是,至少在gcc上,我必须运行两个预处理器才能使它工作。我不知道同样的声音是否必要。

#3


1  

IMO ignoring this warning globally is not a problem. It warns about dummy code, not about potential logic errors caused by typo. That is why I've voted up @MichaelCMS answer.

国际海事组织无视这一全球警告不是问题。它对虚拟代码发出警告,而不是错误导致的潜在逻辑错误。这就是我投票给@MichaelCMS的原因。

But there is a way to disable warning only is some section of code:

但是,有一种方法可以禁用警告,只有部分代码:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-assign"
Q_OBJECT
#pragma clang diagnostic pop

This should do the trick (if I didn't mess up the flag name), but I don't like it, to much boiler plate macros.

这应该很有用(如果我没有把标志名弄乱的话),但是我不喜欢它,对于很多锅盘宏来说。

#1


3  

Try adding -Wno-self-assign to the CPP flags . It should allow you to disable self-assign errors :

尝试向CPP标志添加-Wno-self-assign。它应该允许您禁用自分配错误:

CXXFLAGS= $(CXXFLAGS) -Wno-self-assign 

or

CPPFLAGS=$(CPPFLAGS) -Wno-self-assign

#2


3  

Forgive me for not having clang to test this with, but I felt I should help anyway. Expanding on Marek's answer, there's the possibility of placing the pragma inside another macro expansion. It's a very ugly solution, but that way you only need to define the macro once, instead of spawning pragmas all over your code base.

请原谅我没有使用clang来测试它,但是我觉得无论如何我都应该提供帮助。根据马雷克的答案,有可能把实用主义置于另一个宏观扩张之中。这是一个非常糟糕的解决方案,但是这样您只需要定义一次宏,而不需要在代码库中到处生成实用程序。

#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
}

As you can see, I tested it with gcc(I have no means of testing with clang right now), but that should work fine in clang by substituting "GCC" with "clang" inside the macro(and using -Wself_assign). Applying to your problem(pseudocode):

如您所见,我使用gcc来测试它(我现在没有用clang进行测试的方法),但是如果在clang中使用宏(并使用-Wself_assign)将“gcc”替换为“clang”,那么在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
}

Another ugly downside is that, at least on gcc, I had to run the preprocessor twice for it to work. Can't tell if the same is necessary for clang.

另一个糟糕的缺点是,至少在gcc上,我必须运行两个预处理器才能使它工作。我不知道同样的声音是否必要。

#3


1  

IMO ignoring this warning globally is not a problem. It warns about dummy code, not about potential logic errors caused by typo. That is why I've voted up @MichaelCMS answer.

国际海事组织无视这一全球警告不是问题。它对虚拟代码发出警告,而不是错误导致的潜在逻辑错误。这就是我投票给@MichaelCMS的原因。

But there is a way to disable warning only is some section of code:

但是,有一种方法可以禁用警告,只有部分代码:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-assign"
Q_OBJECT
#pragma clang diagnostic pop

This should do the trick (if I didn't mess up the flag name), but I don't like it, to much boiler plate macros.

这应该很有用(如果我没有把标志名弄乱的话),但是我不喜欢它,对于很多锅盘宏来说。