平息海湾合作委员会的"only available with -std=c++XX or -std=gnu++XX"警告

Silencing gcc's "only available with -std=c++XX or -std=gnu++XX" warning

本文关键字:-std with c++XX 警告 gnu++XX or available only 息海 委员会      更新时间:2023-10-16

后来的语言标准中的某些语言功能非常有用,编译器供应商选择将它们向后移植到早期版本。这方面的典型例子是 if constexpr .

这个简单的程序:

template <typename T>
constexpr int get() {
    if constexpr (sizeof(T) > 10) {
        return 1;
    } else {
        return 0;
    }
}
static_assert(get<int>() == 0, "!");
static_assert(get<char[100]>() == 1, "!");

根据语言规则,技术上需要C++17,并且在C++11中技术上格式不正确......但无论如何,GCC和Clang都可以在-std=c++11上编译它。每个都会发出警告。

Clang会告诉您该警告是什么,以便您可以禁用它:

foo.cxx:3:8: warning: constexpr if is a C++17 extension [-Wc++17-extensions]
    if constexpr (sizeof(T) > 10) {
       ^
1 warning generated.

使用 -Wno-C++17-extensions 编译 clang 不会产生警告。

但 gcc 实际上并没有说警告来自哪里:

foo.cxx: In function ‘constexpr int get()’:
foo.cxx:3:8: warning: ‘if constexpr’ only available with -std=c++17 or -std=gnu++17
     if constexpr (sizeof(T) > 10) {
        ^~~~~~~~~

有没有办法关闭此警告?我知道它"仅在 17 C++可用",但有理由在 17 C++还没有满员。

正如 Marc 所评论的那样,在当前 GCC 版本中停止这些警告的唯一方法是告诉编译器您的代码位于系统标头中。如果代码位于 GCC 的标准包含路径之一(如 /usr/include(中找到的标头中,则会自动发生这种情况,如果代码位于通过 -isystem 选项找到的标头中,则会自动发生。您还可以装饰标头,使 GCC 将其视为系统标头,而不管它位于哪个目录中,如下所示:

#pragma GCC system_header

如果代码不在头文件中,则无法说它位于系统头文件中。任何未 #include 的源文件都不会被视为系统标头,无论它位于哪个目录中或是否使用该 #pragma。

gcc 12 支持禁止显示特定 C++ 版本的警告的选项

https://docs.adacore.com/live/wave/gcc-12.x/html/gcc/gcc.html#Warning-Options

-

Wno-c++17-extensions(在gcc12和clang上都能很好地工作(

请记住,收入是有原因的:他们告诉你,虽然这个编译器可以容忍它,但另一个运行名义上相同版本的语言可能不会。如果你关心可移植性,你应该认真考虑避免这些新功能,或者承认你实际上是在用完全支持它们的较新版本的语言编写。

当然,我意识到我在这里与其他 C 黑客交谈,我们集体因无视可移植性直接编码到硬件而臭名昭著。