10

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.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • Just for completeness sake: what version of gcc are you using? – YSC Apr 15 '19 at 14:47
  • @YSC Any version >= 7.1 – Barry Apr 15 '19 at 14:47
  • Probably one does not want to use "C++11 with some sort of C++17 flavor" for the same reasons that are listed in the linked post. If C++11 and C++17 don't link very well together when used in different translation units why would it be better to mix them in the single translation unit? – user7860670 Apr 15 '19 at 14:53
  • 4
    I don't think you can turn those warnings off (they use pedwarn with an argument of 0 or inform) without saying that your file is a system header or disabling all warnings (`-w`). – Marc Glisse Apr 15 '19 at 14:58
  • `-Wno-` should work for clang, not sure about gcc (it works for *some* warnings, but not all). – Jesper Juhl Apr 15 '19 at 15:06
  • 1
    @JesperJuhl unless you find what to write in lieu of ``, I don't think that helps ^^ And even though, OP asks specifically about gcc. – YSC Apr 15 '19 at 15:14
  • @MarcGlisse is right. It is not currently possible. If you badly want to change this behavior in a future release of GCC, the relevant piece of code is in the function `cp_parser_selection_statement` of gcc/cp/parser.c. A possible patch would be something like: `if (pedantic && cxx_dialect < cxx1z && !in_system_header_at (tok->location))` i.e. adding `pedantic` to the `if` such that this warning is disabled unless the option `-pedantic` is turned on. I have no idea if that would be accepted. Probably not, but its just one line and maybe is worth trying. – metalfox Apr 16 '19 at 13:49
  • 2
    @metalfox I don't think that would be accepted, creating a new -Wc++17-extensions (see c-family/c.opt) seems more likely to pass. Also, a patch needs a testcase (in gcc/testsuite). – Marc Glisse Apr 16 '19 at 14:05

3 Answers3

4

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.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
0

gcc 12 supports the option to suppress the warning of the specific c++ version

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

-Wno-c++17-extensions ( work well both on gcc12 and clang)

zac
  • 111
  • 1
  • 9
0

Remember that the earnings are there for a reason: they tell you that while this compiler may tolerate it, another running what is nominally the same version of the language may not. If you care about portability at all, you should seriously consider either avoiding these new features or admitting that you are really writing in a newer version of the language which fully supports them.

Of course I realize that I'm talking to fellow C hackers here, and we're collectively somewhat notorious for coding directly to the hardware in defiance of portability.

keshlam
  • 7,931
  • 2
  • 19
  • 33