Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

c++11

g++

c++17

Some language features in later language standards are incredibly useful and compiler vendors have chosen to backport them to earlier versions. The quintessential example of this is if constexpr.

This simple program:

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, "!");

technically requires C++17 per the rules of the language, and is technically ill-formed in C++11... but both gcc and clang compile it just fine on -std=c++11 anyway. Each emits a warning.

Clang tells you what that warning is so you can disable it:

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

Compiling on clang with -Wno-C++17-extensions produces no warnings.

But gcc doesn't actually say where the warning comes from:

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) {
        ^~~~~~~~~

Is there a way to turn this warning off? I know it's "only available" on C++17, but there are reasons to not go full C++17 yet.

like image 239
Barry Avatar asked Apr 15 '19 14:04

Barry


1 Answers

As Marc commented, the only way to stop these warnings in current GCC releases is by telling the compiler your code is in a system header. That happens automatically if the code is in a header found in one of GCC's standard include paths like /usr/include, and it happens automatically if the code is in a header found via a -isystem option. You can also decorate a header to make GCC treat it as a system header irrespective of the directory it's in, with:

#pragma GCC system_header

If the code is not in a header file, there's no way to say it's in a system header. Any source file that isn't #include'd won't be considered a system header, no matter what directory it's in or whether you use the #pragma.

like image 67
Jonathan Wakely Avatar answered Nov 15 '22 20:11

Jonathan Wakely