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 >