【问题标题】:Avoid superfluous warnings when compiling Qt code with ccache / clang使用 ccache / clang 编译 Qt 代码时避免多余的警告
【发布时间】: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 添加到“构建环境”

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

【问题讨论】:

    标签: c++ qt clang ccache


    【解决方案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 可以用来禁用所有警告。
    猜你喜欢
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多