On Mon, Aug 07, 2023 at 08:03:05PM -0700, Nikolas Klauser wrote:
> Thanks for the answers!
> 
> There are a few really interesting extensions that I would like to use:
> 
> - inline variables
> - variable templates
> - `if constexpr`
> - fold expressions
> - conditional explicit
> - static operator()

There are multiple problems.

cat /tmp/test.h
#pragma GCC system_header
inline int a = 1;
template <int N> int b = N;
void foo () { if constexpr (true) {} }
template <typename...A> bool bar (A... a) { return (... + a); }
struct S { template <int N> explicit (N == 42) S (int (&)[N]) {} };
struct T { static constexpr bool operator () (S const &x, S const &y) { return 
false; }; };
void baz () { auto a = [](int x, int y) static { return x + y; }; }
cat /tmp/test.C
#include "/tmp/test.h"
g++ -S -std=c++11 -o /tmp/test.{s,C}

The above with GCC 13 doesn't give any warnings, but does with -Wsystem-headers:
In file included from /tmp/test.C:1:
/tmp/test.h:2:1: warning: inline variables are only available with ‘-std=c++17’ 
or ‘-std=gnu++17’ [-Wc++17-extensions]
    2 | inline int a = 1;
      | ^~~~~~
/tmp/test.h:3:22: warning: variable templates only available with ‘-std=c++14’ 
or ‘-std=gnu++14’ [-Wc++14-extensions]
    3 | template <int N> int b = N;
      |                      ^
/tmp/test.h: In function ‘void foo()’:
/tmp/test.h:4:18: warning: ‘if constexpr’ only available with ‘-std=c++17’ or 
‘-std=gnu++17’ [-Wc++17-extensions]
    4 | void foo () { if constexpr (true) {} }
      |                  ^~~~~~~~~
/tmp/test.h: In function ‘bool bar(A ...)’:
/tmp/test.h:5:59: warning: fold-expressions only available with ‘-std=c++17’ or 
‘-std=gnu++17’ [-Wc++17-extensions]
    5 | template <typename...A> bool bar (A... a) { return (... + a); }
      |                                                           ^
/tmp/test.h: At global scope:
/tmp/test.h:6:29: warning: ‘explicit(bool)’ only available with ‘-std=c++20’ or 
‘-std=gnu++20’ [-Wc++20-extensions]
    6 | struct S { template <int N> explicit (N == 42) S (int (&)[N]) {} };
      |                             ^~~~~~~~
/tmp/test.h:7:34: warning: ‘static constexpr bool T::operator()(const S&, const 
S&)’ may be a static member function only with ‘-std=c++23’ or ‘-std=gnu++23’ 
[-Wc++23-extensions]
    7 | struct T { static constexpr bool operator () (S const &x, S const &y) { 
return false; }; };
      |                                  ^~~~~~~~
/tmp/test.h: In function ‘void baz()’:
/tmp/test.h:8:41: warning: ‘static’ only valid in lambda with ‘-std=c++23’ or 
‘-std=gnu++23’ [-Wc++23-extensions]
    8 | void baz () { auto a = [](int x, int y) static { return x + y; }; }
      |                                         ^~~~~~
and with -pedantic-errors -Wsystem-headers even errors:
./xg++ -B ./ -S /tmp/test.C -std=c++11 -pedantic-errors -Wsystem-headers
In file included from /tmp/test.C:1:
/tmp/test.h:2:1: error: inline variables are only available with ‘-std=c++17’ 
or ‘-std=gnu++17’ [-Wc++17-extensions]
    2 | inline int a = 1;
      | ^~~~~~
/tmp/test.h:3:22: error: variable templates only available with ‘-std=c++14’ or 
‘-std=gnu++14’ [-Wc++14-extensions]
    3 | template <int N> int b = N;
      |                      ^
/tmp/test.h: In function ‘void foo()’:
/tmp/test.h:4:18: error: ‘if constexpr’ only available with ‘-std=c++17’ or 
‘-std=gnu++17’ [-Wc++17-extensions]
    4 | void foo () { if constexpr (true) {} }
      |                  ^~~~~~~~~
/tmp/test.h: In function ‘bool bar(A ...)’:
/tmp/test.h:5:59: error: fold-expressions only available with ‘-std=c++17’ or 
‘-std=gnu++17’ [-Wc++17-extensions]
    5 | template <typename...A> bool bar (A... a) { return (... + a); }
      |                                                           ^
/tmp/test.h: At global scope:
/tmp/test.h:6:29: error: ‘explicit(bool)’ only available with ‘-std=c++20’ or 
‘-std=gnu++20’ [-Wc++20-extensions]
    6 | struct S { template <int N> explicit (N == 42) S (int (&)[N]) {} };
      |                             ^~~~~~~~
/tmp/test.h:7:34: error: ‘static constexpr bool T::operator()(const S&, const 
S&)’ may be a static member function only with ‘-std=c++23’ or ‘-std=gnu++23’ 
[-Wc++23-extensions]
    7 | struct T { static constexpr bool operator () (S const &x, S const &y) { 
return false; }; };
      |                                  ^~~~~~~~
/tmp/test.h: In function ‘void baz()’:
/tmp/test.h:8:41: error: ‘static’ only valid in lambda with ‘-std=c++23’ or 
‘-std=gnu++23’ [-Wc++23-extensions]
    8 | void baz () { auto a = [](int x, int y) static { return x + y; }; }
      |                                         ^~~~~~
(so one would need to figure out if __extension__ somewhere around would be
able to quite that up or not, or
#pragma GCC diagnostic ignored "-Wc++14-extensions" (and 17, 20 and 23).

Also, static operator () is only in GCC 13 and later, earlier versions will
error on that.  The -Wc++*-extensions separate warnings are only in GCC 12
and later, before that it will be harder to quiet the warnings selectively.
Similarly, conditional explicit is only GCC 9 and later, if constexpr and
inline vars GCC 7 and later, fold expressions GCC 6 and later, and variable
templates GCC 5 and later.  And in C++98 some of these don't work at all,
if constexpr and static lambdas (because constexpr isn't a keyword
and lambdas aren't supported altogether).

        Jakub

Reply via email to