海湾合作委员会不尊重'编译GCC诊断'以使警告无效 [英] GCC does not honor 'pragma GCC diagnostic' to silence warnings

查看:404
本文介绍了海湾合作委员会不尊重'编译GCC诊断'以使警告无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们最近为一个项目启用了 -Wall 。当GCC在4.7或更高版本(或Clang)时启用它,因为我们可以使用 GCC诊断 来管理高架警告的输出。我们希望通过命令行参数来管理它们,而不是通过 来管理它们。 (我们不想污染命令行,或者要求图书馆用户重新发现需要的内容)。

在GCC 4.8和5.1下,我们捕捉到警告在 -Wunused-variable -Wunused-value - 的GCC诊断块中禁用。 Wunused-function -Wunknown-pragmas 。两个GCC都接受 -fopenmp ,并且都定义 _OPENMP 来回应它,所以我相当肯定它应该是我们应该在响应 #prgam omp ... 时(它 ),从来没有看到 -Wunknown-pragmas em>禁用,但它不是未知)。
$ b

g ++ -DNDEBUG -g2 -O3 -Wall -march = native -pipe -c nbtheory.cpp
nbtheory.cpp:655:0:警告:忽略#pragma omp parallel [-Wunknown-pragmas]
#pragma omp parallel
^
nbtheory.cpp:656:0:warning:忽略#pragma omp节[-Wunknown-pragmas]
#pragma omp节
^
。 ..

在这种特殊情况下, file nbtheroy.cpp 有以下警卫来帮助管理该警告(只显示相关部分,但您可以看到 GitHub链接):

  //定义GCC_DIAGNOSTIC_AWARE如果GCC 4.7或以上。 
#include< misc.h>
...

#if GCC_DIAGNOSTIC_AWARE
#pragma忽略GCC诊断-Wunknown-pragmas
#endif

...
Integer ModularRoot(const Integer& a,const Integer& dp,const Integer& dq,
const Integer& p,const Integer& q,const Integer& u)
{
整数p2,q2;
#pragma omp parallel
#pragma omp sections
{
#pragma omp section
p2 = ModularExponentiation((a%p),dp,p);
#pragma omp section
q2 = ModularExponentiation((a%q),dq,q);
}
返回CRT(p2,p,q2,q,u);
}
...

因为文件是 *。cpp (它有效地 翻译单元),我们 执行开头的#pragma GCC诊断推送和最后的 #pragma GCC诊断推送。 (但是,我们会为包含的头文件执行此操作)。 (我们也尝试过,但没有帮助)。



这里是 GCC_DIAGNOSTIC_AWARE (来自 misc.h ) :

//用于在某些头文件和实现文件中抑制一些警告。
//像CentOS和OpenBSD这样的一些平台使用了不明白的旧编译器-Wno-unknown-pragma。
#define GCC_DIAGNOSTIC_AWARE((__GNUC__> 4 ||(__GNUC__ == 4&& __GNUC_MINOR__> = 7))|| defined(__ clang__))

我知道警卫正在工作,因为在块中添加 #error 会导致错误。此外,注释掉警卫并调用 #pragma GCC诊断忽略-Wunknown-pragmas不起作用。最后,它在Clang下工作正常。



我也遇到了其他警告,比如 -Wunused-variable -Wunused-value -Wunused-function 。我 真的 并不想污染命令行,如潜在重复所示。



我如何在使用 -Wall

时,获取 GCC pragma diagnostic 机制按预期工作可以使GCC下的警告无效




相关的,如果你想重现它(基于GNUmakefile,并且不需要配置或自动工具):

  git clone https://github.com/weidai11/cryptopp.git cryptopp-warn 
cd cryptopp-警告
使

编辑:我们签入了一个补丁禁用 -Wall ,除了Clang。如果你想重现旧行为,那么:

  git clone https:// github。 com / weidai11 / cryptopp.git cryptopp-warn 
cd cryptopp-warn
export CXXFLAGS = - g2 -O3 -DNDEBUG -Wall
make


解决方案

这似乎是 gcc 至少。以下代码:

  #pragma忽略GCC诊断-Wunknown-pragmas
#pragma忽略GCC诊断 - Wuninitialized

int fn(void){
#pragma xyzzy
int x;
return x;
}

int main(void){
return fn();
}

忽略未初始化的 x value,但仍然抱怨编译指示(没有未初始化的编译指示,它会产生 x 的警告为如果您将命令行选项更改为 -Wall -Wno-unknown-pragmas >,那么它忽略它就好了。对于您的特定情况,这是可以的,因为您希望将其应用于整个翻译单元,但它不会允许您从 #pragma 方法获得的细粒度控件(如果它工作的话)。






我去提出GCC的错误报告,但发现它已经存在(#53431 )。

虽然这个特定的bug与 -Wundef 有关,但其中一个注释中的代码片段表明它可能适用于影响预处理器的所有变体(稍加修改以便强调):
$ b


在处理pragmas之前,C ++解析器的词法(预处理),而C解析器将pragmas处理为它会看到它们。
$ b $ p

我们必须以某种方式在 cp / parser.c中解析这些pragma :631 。也许我们可以做一些类似于我们为 cp_parser_initial_pragma 所做的事情,但是在循环中只处理编译指示诊断。当然,它需要一些试验和错误才能做到正确。如果你们中的任何一个人想要尝试并且需要一些帮助,只需在这里或在邮件列表中询问。


这就解释了为什么我们在 -Wuninitialized 中看不到同样的问题,因为在编译过程的后期阶段,在预处理结束时激活了pragmas之后,所以,如果你想看到它更及时地修复(这是三年前提出的),我会建议(像我一样)在GCC bugzilla网站尝试获得一些曝光。

We recently enabled -Wall for a project. Its enabled when GCC is at 4.7 or above (or Clang) because we can use GCC diagnostic to manage the output from the elevated warnings. We want to manage them from the source code, and not via command line arguments. (We don't want to pollute the command line, or ask library users to rediscover what is needed).

Under GCC 4.8 and 5.1, we are catching warnings that were disabled in a GCC diagnostic block for -Wunused-variable, -Wunused-value, -Wunused-function and -Wunknown-pragmas. Both GCCs accept -fopenmp, and both define _OPENMP in response to it, so I'm fairly certain it we should never see a -Wunknown-pragmas in response to #prgam omp ... (it is disabled, but it is not unknown).

g++ -DNDEBUG -g2 -O3 -Wall -march=native -pipe -c nbtheory.cpp
nbtheory.cpp:655:0: warning: ignoring #pragma omp parallel [-Wunknown-pragmas]
  #pragma omp parallel
 ^
nbtheory.cpp:656:0: warning: ignoring #pragma omp sections [-Wunknown-pragmas]
   #pragma omp sections
 ^
...

In this particular case, the file nbtheroy.cpp has the following guard in place to help manage that warning (only relevant parts are shown, but you can see everything from the GitHub link):

// Defines GCC_DIAGNOSTIC_AWARE if GCC 4.7 or above.
#include <misc.h>
...

#if GCC_DIAGNOSTIC_AWARE
# pragma GCC diagnostic ignored "-Wunknown-pragmas"
#endif

...
Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq,
                    const Integer &p, const Integer &q, const Integer &u)
{
    Integer p2, q2;
    #pragma omp parallel
        #pragma omp sections
        {
            #pragma omp section
                p2 = ModularExponentiation((a % p), dp, p);
            #pragma omp section
                q2 = ModularExponentiation((a % q), dq, q);
        }
    return CRT(p2, p, q2, q, u);
}
...

Because the file is *.cpp (its effectively the translation unit), we do not perform a #pragma GCC diagnostic push at the beginning and #pragma GCC diagnostic pop at the end. (We do that for header files that are included, however). (We also tried doing it, but it did not help).

And here is GCC_DIAGNOSTIC_AWARE (from misc.h):

// Used to suppress some warnings in some header and implementation files.
//   Some platforms, like CentOS and OpenBSD, use old compilers that don't understand -Wno-unknown-pragma.
#define GCC_DIAGNOSTIC_AWARE ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__))

I know the guard is working because adding a #error in the block causes an error. Also, commenting out the guard and calling out #pragma GCC diagnostic ignored "-Wunknown-pragmas" does not help. Finally, it works fine under Clang.

I'm also experiencing it for other warnings, like -Wunused-variable, -Wunused-value and -Wunused-function. I really don't want to pollute the command line as suggested with the potential duplicate.

How do I get the GCC pragma diagnostic mechanism to work as expected to silence warnings under GCC when using -Wall?


Related, if you want to reproduce it (its GNUmakefile based, and does not require configurations or autotools):

git clone https://github.com/weidai11/cryptopp.git cryptopp-warn
cd cryptopp-warn
make

EDIT: we checked-in a patch that disables -Wall except for Clang. If you want to reproduce the old behavior, then:

git clone https://github.com/weidai11/cryptopp.git cryptopp-warn
cd cryptopp-warn
export CXXFLAGS="-g2 -O3 -DNDEBUG -Wall"
make

解决方案

This appears to be a bug in gcc at least. The following code:

#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wuninitialized"

int fn(void) {
    #pragma xyzzy
    int x;
    return x;
}

int main (void) {
    return fn();
}

has no problems ignoring the uninitialised x value but still complains about the pragma (without the uninitialized pragma, it generates a warning for x as you'd expect).

If you change the command line options to be -Wall -Wno-unknown-pragmas, then it ignores it just fine. That's okay for your specific case since you want it applied over your entire translation unit but it won't allow the fine-grained control that you would get from the #pragma method (if it worked).


I went to raise a bug report on GCC but found that it already exists (#53431).

While that specific bug has to do with -Wundef, a snippet in one of the comments indicates that it probably applies to all variants affecting the preprocessor (slightly modified for emphasis):

The C++ parser lexes (and preprocesses) before handling the pragmas, whereas the C parser processes the pragmas as it sees them.

We must somehow parse these pragmas also in cp/parser.c:631. Maybe one can do something similar to what we do for cp_parser_initial_pragma, but within the loop and only handling pragma diagnostic. Surely, it will need some trial and error to get it right. If any of you wants to give it a try and need some help, just ask here or in the mailing list.

That explains why we don't see the same problem with -Wuninitialized, because it's detected during later stages of the compilation process, after the pragmas have been activated at the end of preprocessing.

So, if you want to see it fixed in a more timely manner (it was raised over three years ago), I'd suggest (as I have) hassling the GCC bugzilla site to try get some exposure.

这篇关于海湾合作委员会不尊重'编译GCC诊断'以使警告无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆