Luckily most of these aren’t problems for libc++. We only support the latest 
GCC. We can only use `if constexpr` in C++11, but that is already a win I think.

Nikolas

> On Aug 8, 2023, at 12:33 AM, Jakub Jelinek <ja...@redhat.com> wrote:
> 
> 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