GCC不尊重“pragma GCC诊断”来保持警告。

时间:2021-03-27 02:27:41

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).

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

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).

在GCC 4.8和5.1中,我们在GCC诊断块中捕获了一些警告,这些警告在- wunusedvariable、- wunusedvalue、- wunusedfunction和- wunusedmas中禁用。GCCs都接受-fopenmp,并在响应中定义_OPENMP,因此我相当确定,我们不应该看到-Wunknown-pragmas响应#prgam omp…(它是禁用的,但它不是未知的)。

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):

在这个特殊的例子中,文件nbtheroy。cpp有以下的保护措施来帮助管理这个警告(只显示相关的部分,但是您可以从GitHub链接看到所有内容):

// 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).

因为文件是*。cpp(它实际上是一个翻译单元),我们在开始时不执行#pragma GCC的诊断推,在结束时也不执行实用的GCC诊断。(但是,对于包含的头文件,我们这样做)。(我们也试过,但没有用。)

And here is GCC_DIAGNOSTIC_AWARE (from misc.h):

这里是gcc__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.

我知道警卫在工作,因为在块中添加#错误会导致错误。此外,注释掉该保护并调用#pragma GCC诊断忽略“-Wunknown-pragmas”并没有帮助。最后,在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.

我也正在经历其他警告,比如- wunusedvariable, -Wunused-value和-Wunused-function。我真的不想用潜在的复制品来污染命令行。

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

我如何让GCC pragma诊断机制按照预期在GCC使用-Wall时静默警告?


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

相关的,如果您想复制它(基于GNUmakefile的,不需要配置或自动工具):

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:

编辑:我们签入了一个贴片,除了Clang之外,它是可禁用的。如果你想重现旧行为,那么:

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

1 个解决方案

#1


9  

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

这至少是gcc中的一个bug。下面的代码:

#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).

没有忽略未初始化的x值的问题,但仍然抱怨pragma(没有未初始化的pragma,它会像您期望的那样为x生成一个警告)。

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).

如果您更改命令行选项为-Wall -Wno-unknown-pragmas,那么它就会忽略它。这对您的特定情况是可以的,因为您希望它应用于整个翻译单元,但它不会允许您从#pragma方法(如果它有效)中获得细粒度控制。


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

我去报告GCC的bug报告,但是发现它已经存在(#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):

虽然这个特定的bug与-Wundef有关,但是其中一个注释中的一个片段表明它可能适用于影响预处理器的所有变体(稍微修改了一点):

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

在处理pragmas之前,c++解析器lexes(和预处理),而C解析器处理的是它所看到的pragmas。

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.

我们必须以某种方式解析这些pragmas在cp/parser.c:631中。也许我们可以做一些类似于我们为cp_parser_initial_pragma所做的事情,但是在循环中并且只处理pragma诊断。当然,这需要一些尝试和错误来纠正。如果你们中有人想尝试一下,需要一些帮助,请在这里或邮件列表中询问。

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.

这就解释了为什么我们没有看到与-Wuninitialized相同的问题,因为它在编译过程的后期被检测到,因为在预处理结束后,pragmas被激活。

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 bugzilla网站上进行一些争论,以尝试获得一些曝光。

#1


9  

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

这至少是gcc中的一个bug。下面的代码:

#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).

没有忽略未初始化的x值的问题,但仍然抱怨pragma(没有未初始化的pragma,它会像您期望的那样为x生成一个警告)。

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).

如果您更改命令行选项为-Wall -Wno-unknown-pragmas,那么它就会忽略它。这对您的特定情况是可以的,因为您希望它应用于整个翻译单元,但它不会允许您从#pragma方法(如果它有效)中获得细粒度控制。


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

我去报告GCC的bug报告,但是发现它已经存在(#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):

虽然这个特定的bug与-Wundef有关,但是其中一个注释中的一个片段表明它可能适用于影响预处理器的所有变体(稍微修改了一点):

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

在处理pragmas之前,c++解析器lexes(和预处理),而C解析器处理的是它所看到的pragmas。

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.

我们必须以某种方式解析这些pragmas在cp/parser.c:631中。也许我们可以做一些类似于我们为cp_parser_initial_pragma所做的事情,但是在循环中并且只处理pragma诊断。当然,这需要一些尝试和错误来纠正。如果你们中有人想尝试一下,需要一些帮助,请在这里或邮件列表中询问。

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.

这就解释了为什么我们没有看到与-Wuninitialized相同的问题,因为它在编译过程的后期被检测到,因为在预处理结束后,pragmas被激活。

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 bugzilla网站上进行一些争论,以尝试获得一些曝光。