首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >G++忽略_Pragma诊断

G++忽略_Pragma诊断
EN

Stack Overflow用户
提问于 2017-03-28 07:48:11
回答 3查看 621关注 0票数 0

我试图在从宏展开的代码中禁用g++警告。根据我的理解,_Pragma应该遵循宏用法,在用g++编译时不应该触发g++

代码语言:javascript
复制
#include <stdio.h>

#define TEST(expr) \
    int a = 1; \
    _Pragma( "GCC diagnostic push" ) \
    _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" ) \
    if (a <= expr) { \
        printf("filler\n"); \
    } \
    _Pragma( "GCC diagnostic pop" )

int main(){
    int b = 2, c = 3;
    TEST(b == c);
}

当我用g++编译它时,我会得到Wparentheses警告,这是我试图禁用的。

代码语言:javascript
复制
xarn@DESKTOP-B2A3CNC:/mnt/c/ubuntu$ g++ -Wall -Wextra test3.c
test3.c: In function ‘int main()’:
test3.c:8:11: warning: suggest parentheses around comparison in operand of ‘==’ [-Wparentheses]
     if (a <= expr) { \
           ^
test3.c:15:5: note: in expansion of macro ‘TEST’
     TEST(b == c);
     ^

但是,当使用gcc时,它的工作方式与预期的一样。

代码语言:javascript
复制
xarn@DESKTOP-B2A3CNC:/mnt/c/ubuntu$ gcc -Wall -Wextra test3.c
test3.c: In function ‘main’:
test3.c:16:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

我使用的是g++版本4.8.5。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-12-17 10:31:22

在g++处理_Pragma的过程中存在一些长期存在的错误,这些bug在使用gcc前端时并不存在。唯一的解决方案是要么使用足够现代的g++ (IIRC 6+)版本,要么禁用整个TU的警告。

票数 1
EN

Stack Overflow用户

发布于 2019-06-21 11:59:15

Xarn的回答对于理解为什么我们在用g++ < 9.0编译宏时遇到同样的问题很有帮助,但幸运的是,我很固执,没有拿“唯一的解决方案”作为答案。一些更多的挖掘显示,GCC的受影响版本有一个解决办法。

在GNU上,针对这个问题的2012年原始报告中有一位记者随口提到,如果在编译命令中添加-save-temps-no-integrated-cpp_Pragma()将按预期的方式处理。

结果发现,这两个选项中的任何一个都会导致g++ 而不是在默认的流线型模式下运行,这会将预处理和编译阶段折叠为一次。来自g++ 9.1.1的手册页:

代码语言:javascript
复制
    -no-integrated-cpp

       Perform preprocessing as a separate pass before compilation.  By
       default, GCC performs preprocessing as an integrated part of input
       tokenization and parsing.  If this option is provided, the
       appropriate language front end (cc1, cc1plus, or cc1obj for C, C++,
       and Objective-C, respectively) is instead invoked twice, once for
       preprocessing only and once for actual compilation of the
       preprocessed input.  This option may be useful in conjunction with
       the -B or -wrapper options to specify an alternate preprocessor or
       perform additional processing of the program source between normal
       preprocessing and compilation.

这意味着,在我们测试过的GCC版本中,添加-no-integrated-cpp确实可以解决_Pragma()错误--到目前为止,这是5.4,7.3,我相信8.1 --但是对构建的最终结果没有任何影响。(由此可以推断,_Pragma() bug是由单程流线型引入的。)

唯一真正的折衷是,如果您使用启用该选项进行编译,那么编译确实要慢一些。虽然当GCC是受影响的版本之一时,这当然是值得的,但我们在CMake构建设置中使用了一个条件,以确保只在必要时设置-no-integrated-cpp

代码语言:javascript
复制
#### Work around a GCC < 9 bug with handling of _Pragma() in macros
#### See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578
if ((${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") AND
    (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS "9.0.0"))
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-integrated-cpp")
endif()

(如果您的target_compile_options()设置比我们的要好的话,那么用适当的现代调用来代替CMAKE_CXX_FLAGS这种丑陋的野蛮强制。)

票数 1
EN

Stack Overflow用户

发布于 2017-03-28 08:24:33

通常,您只使用警告抑制来处理来自第三方代码的不可避免的警告,这样它们就不会扰乱编译日志。在你的情况下最好是

1)使用正则函数,因为宏是邪恶的。

2)处理警告,在可能中断的表达式周围添加圆括号。

代码语言:javascript
复制
if (a <= (expr)) { 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43063596

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档