GCC support for extensions from later standards

2023-08-02 Thread Nikolas Klauser
Hi everyone!

I'm working on libc++ and we are currently discussing using language extensions 
from later standards 
(https://discourse.llvm.org/t/rfc-use-language-extensions-from-future-standards-in-libc/71898/4).
 By that I mean things like using `if constexpr` with `-std=c++11`. GCC has 
quite a lot of these kinds of conforming extensions, but doesn't document them 
AFAICT. While discussing using these extensions, the question came up what GCCs 
support policy for these is. Aaron was kind enough to answer these questions 
for us on the Clang side. Since I couldn't find anything in the documentation, 
I thought I'd ask here.

So, here are my questions:

Do you expect that these extensions will ever be removed for some reason? If 
yes, what could those reasons be?

Would you be interested in documenting them?

Aaron noted that we should ask the Clang folks before using them, so they can 
evaluated whether the extension makes sense, since they might not be aware of 
them, and some might be broken. So I'd be interested whether you would also 
like us to ask whether you want to actually support these extensions.

Thanks,
Nikolas

Re: GCC support for extensions from later standards

2023-08-07 Thread Nikolas Klauser



On 06.08.23 12:19, Jason Merrill wrote:
On Wed, Aug 2, 2023 at 12:02 PM Nikolas Klauser 
 wrote:


Hi everyone!

I'm working on libc++ and we are currently discussing using
language extensions from later standards

(https://discourse.llvm.org/t/rfc-use-language-extensions-from-future-standards-in-libc/71898/4).
By that I mean things like using `if constexpr` with `-std=c++11`.
GCC has quite a lot of these kinds of conforming extensions, but
doesn't document them AFAICT. While discussing using these
extensions, the question came up what GCCs support policy for
these is. Aaron was kind enough to answer these questions for us
on the Clang side. Since I couldn't find anything in the
documentation, I thought I'd ask here.

So, here are my questions:

Do you expect that these extensions will ever be removed for some
reason? If yes, what could those reasons be?


Potentially, if they don't actually work properly in earlier standard 
modes.  I recently noticed that while we allow DMI and =default in 
C++03 mode with a pedwarn, combining them doesn't work.


Some of the extensions are needed by libstdc++ and are therefore well 
tested; these are extremely unlikely to ever be removed.  libstdc++ 
folks, is there a list of these?


Would you be interested in documenting them?


That would be useful, yes.

There is a patch in review to add __has_feature/__has_extension to 
G++, which would seem like a suitable context for this documentation.


Aaron noted that we should ask the Clang folks before using them,
so they can evaluated whether the extension makes sense, since
they might not be aware of them, and some might be broken. So I'd
be interested whether you would also like us to ask whether you
want to actually support these extensions.


Sounds good.

Jason


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()

(https://godbolt.org/z/5n9Y4h69n)

Is anybody aware of any problems with these extensions? I'd be happy to 
provide a patch to add these extensions to the documentation, but I 
couldn't figure out how to build the documentation without building all 
of gcc.


Nikolas


Re: GCC support for extensions from later standards

2023-08-08 Thread Nikolas Klauser
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  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 b = N;
> void foo () { if constexpr (true) {} }
> template  bool bar (A... a) { return (... + a); }
> struct S { template  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 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  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  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 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  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  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; }; };
&g

Re: GCC support for extensions from later standards

2023-08-08 Thread Nikolas Klauser
Yes, Clang allows it. Most importantly though: you don’t have to be in a 
constexpr function for `if constexpr` to be useful. e.g. the Algorithms aren’t 
constexpr until C++20, but a lot of them have overloads for improving the 
algorithm based on the iterator category. Having `if constexpr` there instead 
of enable_ifs seems like quite a nice improvement to me. The main problem is 
probably that libc++ back-ports a lot of the C++11 stuff to C++03, so in these 
cases `if constexpr` won’t help.

> On Aug 8, 2023, at 9:10 AM, Jonathan Wakely  wrote:
> 
> On Tue, 8 Aug 2023 at 17:07, Jonathan Wakely wrote:
>> 
>> On Tue, 8 Aug 2023 at 17:04, Nikolas Klauser wrote:
>>> 
>>> 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.
>> 
>> Can you use it in C++11 though? The body of a constexpr function must
>> be a single return statement, so if-constexpr isn't allowed.
> 
> Clang allows it with multiple warnings:
> 
> ifc.cc:3:6: warning: constexpr if is a C++17 extension [-Wc++17-extensions]
> if constexpr (sizeof(i) >= 4)
>^
> ifc.cc:3:3: warning: use of this statement in a constexpr function is
> a C++14 extension [-Wc++14-extensions]
> if constexpr (sizeof(i) >= 4)
> ^
> ifc.cc:8:5: warning: multiple return statements in constexpr function
> is a C++14 extension [-Wc++14-extensions]
>   return 0;
>   ^
> ifc.cc:5:5: note: previous return statement is here
>   return i << 3;
>   ^
> 
> But GCC gives a warning for if-constexpr and then an error for the
> invalid function body:
> 
> ifc.cc: In function 'constexpr int f(int)':
> ifc.cc:3:6: warning: 'if constexpr' only available with '-std=c++17'
> or '-std=gnu++17' [-Wc++17-extensions]
>   3 |   if constexpr (sizeof(i) >= 4)
> |  ^
> ifc.cc:9:1: error: body of 'constexpr' function 'constexpr int f(int)'
> not a return-statement
>   9 | }
> | ^