Implementing p0515 - spaceship operator

classic Classic list List threaded Threaded
29 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Implementing p0515 - spaceship operator

Tim van Deurzen
Hi,

I've been spending some time the past few weeks implementing p0515r2,
i.e. the proposal for consistent comparisons for C++ (aka the spaceship
operator). I've received some very valuable help on the IRC channel, but
I'm still a little bit stuck. Note, I'm completely new to the GCC
codebase and am very much still getting oriented.

Following advice from some of the people in IRC channel I implemented
parsing the new token in libcpp and I seem to be successfully parsing it
and creating a new AST node. As this feature is not in the C++ standard
yet, I wanted to add a command line flag to enable usage of the new
operator and ignoring it otherwise. I managed to get cc1plus to accept
the parameter, but it seems that when I invoke my own g++ binary with
that parameter, it complains about unknown parameters.

I'm perfectly happy to dig further on my own, but I get the feeling I'm
missing some documentation / resource somewhere that might help me out.
Is there some documentation about adding and passing around parameters
that will be used both in libcpp and the C++ front-end? What would be
the best place to look to learn more about how part of GCC this is
structured? I want to make sure I go about this correctly.


If this is the wrong place to ask for help, please redirect me, so that
I don't unnecessarily spam the wrong mailing list :-).


Kind regards,

Tim.



Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jason Merrill
On Mon, Jan 8, 2018 at 4:07 PM, Tim van Deurzen <[hidden email]> wrote:
> I've been spending some time the past few weeks implementing p0515r2,
> i.e. the proposal for consistent comparisons for C++ (aka the spaceship
> operator).

Great!

> I've received some very valuable help on the IRC channel, but
> I'm still a little bit stuck. Note, I'm completely new to the GCC
> codebase and am very much still getting oriented.
>
> Following advice from some of the people in IRC channel I implemented
> parsing the new token in libcpp and I seem to be successfully parsing it
> and creating a new AST node. As this feature is not in the C++ standard
> yet, I wanted to add a command line flag to enable usage of the new
> operator and ignoring it otherwise. I managed to get cc1plus to accept
> the parameter, but it seems that when I invoke my own g++ binary with
> that parameter, it complains about unknown parameters.
>
> I'm perfectly happy to dig further on my own, but I get the feeling I'm
> missing some documentation / resource somewhere that might help me out.
> Is there some documentation about adding and passing around parameters
> that will be used both in libcpp and the C++ front-end? What would be
> the best place to look to learn more about how part of GCC this is
> structured? I want to make sure I go about this correctly.

There's a gccint.info documentation file, the Options node seems like
what you're looking for.  You will want to add a new option to
c-family/c.opt.

> If this is the wrong place to ask for help, please redirect me, so that
> I don't unnecessarily spam the wrong mailing list :-).

I'm not sure whether gcc@ or gcc-patches@ is better for this sort of
question (without a patch).  I tend to miss a lot that goes by on the
mailing list, so CCing me directly about C++ changes is also helpful.

Jason
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jonathan Wakely-4
On 8 January 2018 at 22:07, Jason Merrill wrote:

> On Mon, Jan 8, 2018 at 4:07 PM, Tim van Deurzen <[hidden email]> wrote:
>> I've been spending some time the past few weeks implementing p0515r2,
>> i.e. the proposal for consistent comparisons for C++ (aka the spaceship
>> operator).
>
> Great!
>
>> I've received some very valuable help on the IRC channel, but
>> I'm still a little bit stuck. Note, I'm completely new to the GCC
>> codebase and am very much still getting oriented.
>>
>> Following advice from some of the people in IRC channel I implemented
>> parsing the new token in libcpp and I seem to be successfully parsing it
>> and creating a new AST node. As this feature is not in the C++ standard
>> yet, I wanted to add a command line flag to enable usage of the new
>> operator and ignoring it otherwise. I managed to get cc1plus to accept
>> the parameter, but it seems that when I invoke my own g++ binary with
>> that parameter, it complains about unknown parameters.
>>
>> I'm perfectly happy to dig further on my own, but I get the feeling I'm
>> missing some documentation / resource somewhere that might help me out.
>> Is there some documentation about adding and passing around parameters
>> that will be used both in libcpp and the C++ front-end? What would be
>> the best place to look to learn more about how part of GCC this is
>> structured? I want to make sure I go about this correctly.
>
> There's a gccint.info documentation file, the Options node seems like
> what you're looking for.  You will want to add a new option to
> c-family/c.opt.

operator<=> is now in the working paper though, so does it need its
own option? IMHO it should just be enabled for -std=c++2a and
-std=gnu++2a, and not otherwise.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jason Merrill
On Mon, Jan 8, 2018 at 5:13 PM, Jonathan Wakely <[hidden email]> wrote:

> On 8 January 2018 at 22:07, Jason Merrill wrote:
>> On Mon, Jan 8, 2018 at 4:07 PM, Tim van Deurzen <[hidden email]> wrote:
>>> I've been spending some time the past few weeks implementing p0515r2,
>>> i.e. the proposal for consistent comparisons for C++ (aka the spaceship
>>> operator).
>>
>> Great!
>>
>>> I've received some very valuable help on the IRC channel, but
>>> I'm still a little bit stuck. Note, I'm completely new to the GCC
>>> codebase and am very much still getting oriented.
>>>
>>> Following advice from some of the people in IRC channel I implemented
>>> parsing the new token in libcpp and I seem to be successfully parsing it
>>> and creating a new AST node. As this feature is not in the C++ standard
>>> yet, I wanted to add a command line flag to enable usage of the new
>>> operator and ignoring it otherwise. I managed to get cc1plus to accept
>>> the parameter, but it seems that when I invoke my own g++ binary with
>>> that parameter, it complains about unknown parameters.
>>>
>>> I'm perfectly happy to dig further on my own, but I get the feeling I'm
>>> missing some documentation / resource somewhere that might help me out.
>>> Is there some documentation about adding and passing around parameters
>>> that will be used both in libcpp and the C++ front-end? What would be
>>> the best place to look to learn more about how part of GCC this is
>>> structured? I want to make sure I go about this correctly.
>>
>> There's a gccint.info documentation file, the Options node seems like
>> what you're looking for.  You will want to add a new option to
>> c-family/c.opt.
>
> operator<=> is now in the working paper though, so does it need its
> own option? IMHO it should just be enabled for -std=c++2a and
> -std=gnu++2a, and not otherwise.

Ah, good point.

Jason
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Martin Sebor-2
In reply to this post by Tim van Deurzen
On 01/08/2018 02:07 PM, Tim van Deurzen wrote:

> Hi,
>
> I've been spending some time the past few weeks implementing p0515r2,
> i.e. the proposal for consistent comparisons for C++ (aka the spaceship
> operator). I've received some very valuable help on the IRC channel, but
> I'm still a little bit stuck. Note, I'm completely new to the GCC
> codebase and am very much still getting oriented.
>
> Following advice from some of the people in IRC channel I implemented
> parsing the new token in libcpp and I seem to be successfully parsing it
> and creating a new AST node. As this feature is not in the C++ standard
> yet, I wanted to add a command line flag to enable usage of the new
> operator and ignoring it otherwise. I managed to get cc1plus to accept
> the parameter, but it seems that when I invoke my own g++ binary with
> that parameter, it complains about unknown parameters.

As Jonathan mentioned, you may not need a new option for this.
But it's useful to know how to add one in any case.  Reading
the manual is a good idea but the easiest way to actually add
one by far is to look at a simple change that adds in git or
svn log one and follow its example.  This command will give you
such a list: git log -p --grep="New option"  Then just look for
an option that affects the front-end.  A warning options might
be a good example.

Martin

>
> I'm perfectly happy to dig further on my own, but I get the feeling I'm
> missing some documentation / resource somewhere that might help me out.
> Is there some documentation about adding and passing around parameters
> that will be used both in libcpp and the C++ front-end? What would be
> the best place to look to learn more about how part of GCC this is
> structured? I want to make sure I go about this correctly.
>
>
> If this is the wrong place to ask for help, please redirect me, so that
> I don't unnecessarily spam the wrong mailing list :-).
>
>
> Kind regards,
>
> Tim.
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Nathan Sidwell-2
In reply to this post by Jason Merrill
On 01/08/2018 05:07 PM, Jason Merrill wrote:
> On Mon, Jan 8, 2018 at 4:07 PM, Tim van Deurzen <[hidden email]> wrote:

> There's a gccint.info documentation file, the Options node seems like
> what you're looking for.  You will want to add a new option to
> c-family/c.opt.

diffing between branches/c++-modules and trunk may be educational, as
that has to do similar things to enable the new keywords.

nathan

--
Nathan Sidwell
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Tim van Deurzen
In reply to this post by Jason Merrill


On 01/08/2018 11:28 PM, Jason Merrill wrote:

> On Mon, Jan 8, 2018 at 5:13 PM, Jonathan Wakely <[hidden email]> wrote:
>> On 8 January 2018 at 22:07, Jason Merrill wrote:
>>> On Mon, Jan 8, 2018 at 4:07 PM, Tim van Deurzen <[hidden email]> wrote:
>>>> I've been spending some time the past few weeks implementing p0515r2,
>>>> i.e. the proposal for consistent comparisons for C++ (aka the spaceship
>>>> operator).
>>> Great!
>>>
>>>> I've received some very valuable help on the IRC channel, but
>>>> I'm still a little bit stuck. Note, I'm completely new to the GCC
>>>> codebase and am very much still getting oriented.
>>>>
>>>> Following advice from some of the people in IRC channel I implemented
>>>> parsing the new token in libcpp and I seem to be successfully parsing it
>>>> and creating a new AST node. As this feature is not in the C++ standard
>>>> yet, I wanted to add a command line flag to enable usage of the new
>>>> operator and ignoring it otherwise. I managed to get cc1plus to accept
>>>> the parameter, but it seems that when I invoke my own g++ binary with
>>>> that parameter, it complains about unknown parameters.
>>>>
>>>> I'm perfectly happy to dig further on my own, but I get the feeling I'm
>>>> missing some documentation / resource somewhere that might help me out.
>>>> Is there some documentation about adding and passing around parameters
>>>> that will be used both in libcpp and the C++ front-end? What would be
>>>> the best place to look to learn more about how part of GCC this is
>>>> structured? I want to make sure I go about this correctly.
>>> There's a gccint.info documentation file, the Options node seems like
>>> what you're looking for.  You will want to add a new option to
>>> c-family/c.opt.
>> operator<=> is now in the working paper though, so does it need its
>> own option? IMHO it should just be enabled for -std=c++2a and
>> -std=gnu++2a, and not otherwise.
> Ah, good point.
>
> Jason
That makes sense, I'll just use the c++2a and gnu++2a flags. Though I'll
still take some time to figure out how options work, so that I can add
any toggles that (e.g. for warnings) that might be specific to operator<=>.

Just to confirm with you, it does make sense to conditionally parse the
token for operator<=> in libcpp (i.e. only when the cxx standard being
used is >=2a)? I'm just wondering if this does not accidentally affect
other front-ends using libcpp?

Tim.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jonathan Wakely-4
On 9 Jan 2018 10:56 p.m., "Tim van Deurzen"  <[hidden email]>wrote:


Just to confirm with you, it does make sense to conditionally parse the
token for operator<=> in libcpp (i.e. only when the cxx standard being used
is >=2a)? I'm just wondering if this does not accidentally affect other
front-ends using libcpp?


Other front ends won't setthe language to C++2a.

I think the relevant check is:

      if (CPP_OPTION (pfile, lang) == CLK_CXX2A
          || CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)

This can only be true for a C++ source file when the standard is C++2a.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Tim van Deurzen
On 01/10/2018 02:00 PM, Jonathan Wakely wrote:

> On 9 Jan 2018 10:56 p.m., "Tim van Deurzen" wrote:
>
>
>     Just to confirm with you, it does make sense to conditionally
>     parse the token for operator<=> in libcpp (i.e. only when the cxx
>     standard being used is >=2a)? I'm just wondering if this does not
>     accidentally affect other front-ends using libcpp?
>
>
> Other front ends won't setthe language to C++2a.
>
> I think the relevant check is:
>
>       if (CPP_OPTION (pfile, lang) == CLK_CXX2A
>           || CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)
>
> This can only be true for a C++ source file when the standard is C++2a.
>
Ok, good to know, then I'll proceed like this. Thank you!

Tim.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jakub Jelinek
On Wed, Jan 10, 2018 at 10:24:00PM +0100, Tim van Deurzen wrote:

> On 01/10/2018 02:00 PM, Jonathan Wakely wrote:
>
> > On 9 Jan 2018 10:56 p.m., "Tim van Deurzen" wrote:
> >
> >
> >     Just to confirm with you, it does make sense to conditionally
> >     parse the token for operator<=> in libcpp (i.e. only when the cxx
> >     standard being used is >=2a)? I'm just wondering if this does not
> >     accidentally affect other front-ends using libcpp?
> >
> >
> > Other front ends won't setthe language to C++2a.
> >
> > I think the relevant check is:
> >
> >       if (CPP_OPTION (pfile, lang) == CLK_CXX2A
> >           || CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)
> >
> > This can only be true for a C++ source file when the standard is C++2a.
> >
> Ok, good to know, then I'll proceed like this. Thank you!

Well, the usual way of doing stuff is add another field to
struct lang_flags, add it to the lang_defaults table, add it to
struct cpp_options too and then use CPP_OPTION (pfile, spaceship) or so,
e.g. look how va_opt etc. are implemented.

        Jakub
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Tim van Deurzen
Hi Jakub,


On 01/10/2018 10:32 PM, Jakub Jelinek wrote:

> On Wed, Jan 10, 2018 at 10:24:00PM +0100, Tim van Deurzen wrote:
>> On 01/10/2018 02:00 PM, Jonathan Wakely wrote:
>>
>>> On 9 Jan 2018 10:56 p.m., "Tim van Deurzen" wrote:
>>>
>>>
>>>      Just to confirm with you, it does make sense to conditionally
>>>      parse the token for operator<=> in libcpp (i.e. only when the cxx
>>>      standard being used is >=2a)? I'm just wondering if this does not
>>>      accidentally affect other front-ends using libcpp?
>>>
>>>
>>> Other front ends won't setthe language to C++2a.
>>>
>>> I think the relevant check is:
>>>
>>>        if (CPP_OPTION (pfile, lang) == CLK_CXX2A
>>>            || CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)
>>>
>>> This can only be true for a C++ source file when the standard is C++2a.
>>>
>> Ok, good to know, then I'll proceed like this. Thank you!
> Well, the usual way of doing stuff is add another field to
> struct lang_flags, add it to the lang_defaults table, add it to
> struct cpp_options too and then use CPP_OPTION (pfile, spaceship) or so,
> e.g. look how va_opt etc. are implemented.
>
> Jakub
I think, I got almost all of that at some point, but probably missed
something somewhere.
For now I will proceed with the cxx standard flags. If I add any kind of
warning or toggle I'll have a good idea where to start at this point.
Thank you!

Tim.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

David Brown-4
In reply to this post by Jonathan Wakely-4
On 10/01/18 14:00, Jonathan Wakely wrote:
> On 9 Jan 2018 10:56 p.m., "Tim van Deurzen"  <[hidden email]>wrote:
>
>
> Just to confirm with you, it does make sense to conditionally parse the
> token for operator<=> in libcpp (i.e. only when the cxx standard being used
> is >=2a)? I'm just wondering if this does not accidentally affect other
> front-ends using libcpp?
>

Maybe it is easier to say "gcc supports <=> in C++2a, and as an
extension also supports it in C and C++ of any standard" ?  I don't
believe there is any way for it to conflict with existing valid code, so
it would do no harm as a gcc extension like that - and C users can then
use it too.

>
> Other front ends won't setthe language to C++2a.
>
> I think the relevant check is:
>
>       if (CPP_OPTION (pfile, lang) == CLK_CXX2A
>           || CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)
>
> This can only be true for a C++ source file when the standard is C++2a.
>

Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jonathan Wakely-4
t all cleaOn 11 January 2018 at 10:05, David Brown wrote:
> Maybe it is easier to say "gcc supports <=> in C++2a, and as an
> extension also supports it in C and C++ of any standard" ?  I don't
> believe there is any way for it to conflict with existing valid code, so
> it would do no harm as a gcc extension like that - and C users can then
> use it too.

It's not very useful in C because you need the comparison category
types, which are classes defined in <compare> (see
http://en.cppreference.com/w/cpp/header/compare)

C doesn't have those types, and can't define anything close.

And it's non-conforming to declare those types in pre-C++2a, because
the names could be used by user programs.

Potentially the types could be defined with reserved names like
__strong_ordering, and then make std::strong_ordering a typedef for
that, but there are also changes to the language spec that go with the
new operator, and enabling those pre-C++2a could change the meaning of
valid code.

So it's not ar it does no harm.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jonathan Wakely-4
On 11 January 2018 at 10:13, Jonathan Wakely wrote:

> t all cleaOn 11 January 2018 at 10:05, David Brown wrote:
>> Maybe it is easier to say "gcc supports <=> in C++2a, and as an
>> extension also supports it in C and C++ of any standard" ?  I don't
>> believe there is any way for it to conflict with existing valid code, so
>> it would do no harm as a gcc extension like that - and C users can then
>> use it too.
>
> It's not very useful in C because you need the comparison category
> types, which are classes defined in <compare> (see
> http://en.cppreference.com/w/cpp/header/compare)
>
> C doesn't have those types, and can't define anything close.
>
> And it's non-conforming to declare those types in pre-C++2a, because
> the names could be used by user programs.
>
> Potentially the types could be defined with reserved names like
> __strong_ordering, and then make std::strong_ordering a typedef for
> that, but there are also changes to the language spec that go with the
> new operator, and enabling those pre-C++2a could change the meaning of
> valid code.
>
> So it's not ar it does no harm.

Sorry, Firefox keeps jumping the cursor around and garbled this text
as I entered it. That should read:

So it's not at all clear it does no harm.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

David Brown-4
In reply to this post by Jonathan Wakely-4
On 11/01/18 11:13, Jonathan Wakely wrote:

> t all cleaOn 11 January 2018 at 10:05, David Brown wrote:
>> Maybe it is easier to say "gcc supports <=> in C++2a, and as an
>> extension also supports it in C and C++ of any standard" ?  I don't
>> believe there is any way for it to conflict with existing valid code, so
>> it would do no harm as a gcc extension like that - and C users can then
>> use it too.
>
> It's not very useful in C because you need the comparison category
> types, which are classes defined in <compare> (see
> http://en.cppreference.com/w/cpp/header/compare)
>
> C doesn't have those types, and can't define anything close.
>

Surely you can get very close by simply returning an int, value -1, 0 or
1?  That is what other languages (like PHP) do for their <=> operator.
There are complications - such as for floating point when you have NaNs.
 But I think you could have a very successful operator if you defined "a
<=> b" to be the same as "(a > b) - (a < b)".

Whether it would be particularly /useful/ or not is another matter.  I
was thinking mainly in terms of saving effort when making C++2a support
- rather than having to making the new operator conditional on a
particular version of the standards, it could be accepted in any version.

> And it's non-conforming to declare those types in pre-C++2a, because
> the names could be used by user programs.
>
> Potentially the types could be defined with reserved names like
> __strong_ordering, and then make std::strong_ordering a typedef for
> that, but there are also changes to the language spec that go with the
> new operator, and enabling those pre-C++2a could change the meaning of
> valid code.
>
> So it's not ar it does no harm.
>

Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jonathan Wakely-4
On 11 January 2018 at 11:28, David Brown wrote:

> On 11/01/18 11:13, Jonathan Wakely wrote:
>> t all cleaOn 11 January 2018 at 10:05, David Brown wrote:
>>> Maybe it is easier to say "gcc supports <=> in C++2a, and as an
>>> extension also supports it in C and C++ of any standard" ?  I don't
>>> believe there is any way for it to conflict with existing valid code, so
>>> it would do no harm as a gcc extension like that - and C users can then
>>> use it too.
>>
>> It's not very useful in C because you need the comparison category
>> types, which are classes defined in <compare> (see
>> http://en.cppreference.com/w/cpp/header/compare)
>>
>> C doesn't have those types, and can't define anything close.
>>
>
> Surely you can get very close by simply returning an int, value -1, 0 or
> 1?  That is what other languages (like PHP) do for their <=> operator.
> There are complications - such as for floating point when you have NaNs.
>  But I think you could have a very successful operator if you defined "a
> <=> b" to be the same as "(a > b) - (a < b)".
>
> Whether it would be particularly /useful/ or not is another matter.  I
> was thinking mainly in terms of saving effort when making C++2a support
> - rather than having to making the new operator conditional on a
> particular version of the standards, it could be accepted in any version.

It seems like the wrong trade-off. We have dozens of features that
depend on the standards mode, we know how to do that.

Simply slamming a new language feature in all modes (*and* in a
different language with a different front-end!) to save a small amount
of effort doesn't seem like a good idea to me. Especially if it then
doesn't even work the same pre-C++2a, as know we need to test it in
additional ways.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jonathan Wakely-4
On 11 January 2018 at 11:32, Jonathan Wakely wrote:

> On 11 January 2018 at 11:28, David Brown wrote:
>> On 11/01/18 11:13, Jonathan Wakely wrote:
>>> t all cleaOn 11 January 2018 at 10:05, David Brown wrote:
>>>> Maybe it is easier to say "gcc supports <=> in C++2a, and as an
>>>> extension also supports it in C and C++ of any standard" ?  I don't
>>>> believe there is any way for it to conflict with existing valid code, so
>>>> it would do no harm as a gcc extension like that - and C users can then
>>>> use it too.
>>>
>>> It's not very useful in C because you need the comparison category
>>> types, which are classes defined in <compare> (see
>>> http://en.cppreference.com/w/cpp/header/compare)
>>>
>>> C doesn't have those types, and can't define anything close.
>>>
>>
>> Surely you can get very close by simply returning an int, value -1, 0 or
>> 1?  That is what other languages (like PHP) do for their <=> operator.
>> There are complications - such as for floating point when you have NaNs.
>>  But I think you could have a very successful operator if you defined "a
>> <=> b" to be the same as "(a > b) - (a < b)".
>>
>> Whether it would be particularly /useful/ or not is another matter.  I
>> was thinking mainly in terms of saving effort when making C++2a support
>> - rather than having to making the new operator conditional on a
>> particular version of the standards, it could be accepted in any version.
>
> It seems like the wrong trade-off. We have dozens of features that
> depend on the standards mode, we know how to do that.
>
> Simply slamming a new language feature in all modes (*and* in a
> different language with a different front-end!) to save a small amount
> of effort doesn't seem like a good idea to me. Especially if it then
> doesn't even work the same pre-C++2a, as know we need to test it in

s/know/now/

> additional ways.
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

David Brown-4
In reply to this post by Jonathan Wakely-4
On 11/01/18 12:32, Jonathan Wakely wrote:

> On 11 January 2018 at 11:28, David Brown wrote:
>> On 11/01/18 11:13, Jonathan Wakely wrote:
>>> t all cleaOn 11 January 2018 at 10:05, David Brown wrote:
>>>> Maybe it is easier to say "gcc supports <=> in C++2a, and as an
>>>> extension also supports it in C and C++ of any standard" ?  I don't
>>>> believe there is any way for it to conflict with existing valid code, so
>>>> it would do no harm as a gcc extension like that - and C users can then
>>>> use it too.
>>>
>>> It's not very useful in C because you need the comparison category
>>> types, which are classes defined in <compare> (see
>>> http://en.cppreference.com/w/cpp/header/compare)
>>>
>>> C doesn't have those types, and can't define anything close.
>>>
>>
>> Surely you can get very close by simply returning an int, value -1, 0 or
>> 1?  That is what other languages (like PHP) do for their <=> operator.
>> There are complications - such as for floating point when you have NaNs.
>>  But I think you could have a very successful operator if you defined "a
>> <=> b" to be the same as "(a > b) - (a < b)".
>>
>> Whether it would be particularly /useful/ or not is another matter.  I
>> was thinking mainly in terms of saving effort when making C++2a support
>> - rather than having to making the new operator conditional on a
>> particular version of the standards, it could be accepted in any version.
>
> It seems like the wrong trade-off. We have dozens of features that
> depend on the standards mode, we know how to do that.
>
> Simply slamming a new language feature in all modes (*and* in a
> different language with a different front-end!) to save a small amount
> of effort doesn't seem like a good idea to me. Especially if it then
> doesn't even work the same pre-C++2a, as know we need to test it in
> additional ways.
>

Fair enough.  I was merely thinking it might make the development a
little easier by avoiding more feature testing in the front ends.  And
gcc has a history of making some features of one language or standard
available in others as gcc extensions.  (Sometimes I find these useful
in my coding - though I can't think off-hand for a use of <=> in my own
programs.)

But I see pre-C++2a would be a problem here.  You can't make it match
the C++2a version, because you don't have the types available - and you
wouldn't want to make it have different types that are incompatible with
the C++2a version.  It would be fine with a -1, 0, 1 int result in C -
but not in pre-C++2a.



Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Joseph Myers
In reply to this post by David Brown-4
On Thu, 11 Jan 2018, David Brown wrote:

> Maybe it is easier to say "gcc supports <=> in C++2a, and as an
> extension also supports it in C and C++ of any standard" ?  I don't
> believe there is any way for it to conflict with existing valid code, so
> it would do no harm as a gcc extension like that - and C users can then
> use it too.

As per previous IRC discussion, changing the lexing to support this
pp-token can break valid code in previous standards, e.g. code
concatenating <=> and >, then stringizing the result (the C++ proposal for
adding this feature also notes some obscure cases where the character
sequence <=> can actually occur as tokens, not just pp-tokens -
"X<&Y::operator<=>" and "x+&operator<=>y" - so of course patches adding
this feature should add testcases using such cases with older -std=
options).

Changes to cpp_avoid_paste (so that preprocessed output does not put a
pp-token starting with > immediately after <=) do not need to be
conditional on the standard version, however.

--
Joseph S. Myers
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Implementing p0515 - spaceship operator

Jakub Jelinek
On Thu, Jan 11, 2018 at 02:06:06PM +0000, Joseph Myers wrote:

> On Thu, 11 Jan 2018, David Brown wrote:
>
> > Maybe it is easier to say "gcc supports <=> in C++2a, and as an
> > extension also supports it in C and C++ of any standard" ?  I don't
> > believe there is any way for it to conflict with existing valid code, so
> > it would do no harm as a gcc extension like that - and C users can then
> > use it too.
>
> As per previous IRC discussion, changing the lexing to support this
> pp-token can break valid code in previous standards, e.g. code
> concatenating <=> and >, then stringizing the result (the C++ proposal for
> adding this feature also notes some obscure cases where the character
> sequence <=> can actually occur as tokens, not just pp-tokens -
> "X<&Y::operator<=>" and "x+&operator<=>y" - so of course patches adding
> this feature should add testcases using such cases with older -std=
> options).
>
> Changes to cpp_avoid_paste (so that preprocessed output does not put a
> pp-token starting with > immediately after <=) do not need to be
> conditional on the standard version, however.

Here is a patch that attempts to implement this (in libcpp + gcc/testsuite
only so far).
It needs to be parsed and handled in the C++ FE obviously, which is missing.

2018-08-30  Jakub Jelinek  <[hidden email]>

        P0515R3 - Consistent comparison
        * include/cpplib.h (TTYPE_TABLE): Add CPP_SPACESHIP.
        (struct cpp_options): Add spaceship field.
        * init.c (struct lang_flags): Add spaceship field.
        (lang_defaults): Add spaceship column.
        (cpp_set_lang): Initialize CPP_OPTION (pfile, spaceship).
        * lex.c (_cpp_lex_direct): Lex CPP_SPACESHIP.
        (cpp_avoid_paste): Avoid pasting <= with >.

        * c-c++-common/cpp/spaceship-1.c: New test.
        * g++.dg/cpp/spaceship-1.C: New test.

--- libcpp/include/cpplib.h.jj 2018-08-26 22:43:12.510939169 +0200
+++ libcpp/include/cpplib.h 2018-08-30 18:55:55.483035882 +0200
@@ -91,6 +91,7 @@ struct _cpp_file;
   OP(XOR_EQ, "^=") \
   OP(RSHIFT_EQ, ">>=") \
   OP(LSHIFT_EQ, "<<=") \
+  OP(SPACESHIP, "<=>") \
   /* Digraphs together, beginning with CPP_FIRST_DIGRAPH.  */ \
   OP(HASH, "#") /* digraphs */ \
   OP(PASTE, "##") \
@@ -480,6 +481,9 @@ struct cpp_options
   /* Nonzero for C++2a __VA_OPT__ feature.  */
   unsigned char va_opt;
 
+  /* Nonzero for C++2a <=> operator.  */
+  unsigned char spaceship;
+
   /* Holds the name of the target (execution) character set.  */
   const char *narrow_charset;
 
--- libcpp/init.c.jj 2018-08-26 22:43:13.760918150 +0200
+++ libcpp/init.c 2018-08-30 18:57:41.479297007 +0200
@@ -92,30 +92,31 @@ struct lang_flags
   char trigraphs;
   char utf8_char_literals;
   char va_opt;
+  char spaceship;
 };
 
 static const struct lang_flags lang_defaults[] =
-{ /*              c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt */
-  /* GNUC89   */  { 0,  0,  1,  0,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1 },
-  /* GNUC99   */  { 1,  0,  1,  1,  0,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1 },
-  /* GNUC11   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1 },
-  /* GNUC17   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1 },
-  /* STDC89   */  { 0,  0,  0,  0,  0,  1,  0,   0,   0,   0,    0,     0,     1,   0,      0 },
-  /* STDC94   */  { 0,  0,  0,  0,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0 },
-  /* STDC99   */  { 1,  0,  1,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0 },
-  /* STDC11   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0 },
-  /* STDC17   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0 },
-  /* GNUCXX   */  { 0,  1,  1,  1,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1 },
-  /* CXX98    */  { 0,  1,  0,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0 },
-  /* GNUCXX11 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    0,     0,     0,   0,      1 },
-  /* CXX11    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    0,     0,     1,   0,      0 },
-  /* GNUCXX14 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   0,      1 },
-  /* CXX14    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    1,     1,     1,   0,      0 },
-  /* GNUCXX17 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1 },
-  /* CXX17    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      0 },
-  /* GNUCXX2A */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1 },
-  /* CXX2A    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      1 },
-  /* ASM      */  { 0,  0,  1,  0,  0,  0,  0,   0,   0,   0,    0,     0,     0,   0,      0 }
+{ /*              c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt spaceship */
+  /* GNUC89   */  { 0,  0,  1,  0,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1,   0 },
+  /* GNUC99   */  { 1,  0,  1,  1,  0,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   0 },
+  /* GNUC11   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   0 },
+  /* GNUC17   */  { 1,  0,  1,  1,  1,  0,  1,   1,   1,   0,    0,     0,     0,   0,      1,   0 },
+  /* STDC89   */  { 0,  0,  0,  0,  0,  1,  0,   0,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* STDC94   */  { 0,  0,  0,  0,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* STDC99   */  { 1,  0,  1,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* STDC11   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* STDC17   */  { 1,  0,  1,  1,  1,  1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* GNUCXX   */  { 0,  1,  1,  1,  0,  0,  1,   0,   0,   0,    0,     0,     0,   0,      1,   0 },
+  /* CXX98    */  { 0,  1,  0,  1,  0,  1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0 },
+  /* GNUCXX11 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    0,     0,     0,   0,      1,   0 },
+  /* CXX11    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    0,     0,     1,   0,      0,   0 },
+  /* GNUCXX14 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   0,      1,   0 },
+  /* CXX14    */  { 1,  1,  0,  1,  1,  1,  1,   1,   1,   1,    1,     1,     1,   0,      0,   0 },
+  /* GNUCXX17 */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   0 },
+  /* CXX17    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      0,   0 },
+  /* GNUCXX2A */  { 1,  1,  1,  1,  1,  0,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1 },
+  /* CXX2A    */  { 1,  1,  1,  1,  1,  1,  1,   1,   1,   1,    1,     1,     0,   1,      1,   1 },
+  /* ASM      */  { 0,  0,  1,  0,  0,  0,  0,   0,   0,   0,    0,     0,     0,   0,      0,   0 }
 };
 
 /* Sets internal flags correctly for a given language.  */
@@ -141,6 +142,7 @@ cpp_set_lang (cpp_reader *pfile, enum c_
   CPP_OPTION (pfile, trigraphs) = l->trigraphs;
   CPP_OPTION (pfile, utf8_char_literals) = l->utf8_char_literals;
   CPP_OPTION (pfile, va_opt) = l->va_opt;
+  CPP_OPTION (pfile, spaceship) = l->spaceship;
 }
 
 /* Initialize library global state.  */
--- libcpp/lex.c.jj 2018-08-26 22:43:14.784900935 +0200
+++ libcpp/lex.c 2018-08-30 19:02:43.261340974 +0200
@@ -2963,7 +2963,11 @@ _cpp_lex_direct (cpp_reader *pfile)
 
       result->type = CPP_LESS;
       if (*buffer->cur == '=')
- buffer->cur++, result->type = CPP_LESS_EQ;
+ {
+  buffer->cur++, result->type = CPP_LESS_EQ;
+  if (*buffer->cur == '>' && CPP_OPTION (pfile, spaceship))
+    buffer->cur++, result->type = CPP_SPACESHIP;
+ }
       else if (*buffer->cur == '<')
  {
   buffer->cur++;
@@ -3466,6 +3470,7 @@ cpp_avoid_paste (cpp_reader *pfile, cons
  || (CPP_OPTION (pfile, objc)
     && token1->val.str.text[0] == '@'
     && (b == CPP_NAME || b == CPP_STRING)));
+    case CPP_LESS_EQ: return c == '>';
     case CPP_STRING:
     case CPP_WSTRING:
     case CPP_UTF8STRING:
--- gcc/testsuite/c-c++-common/cpp/spaceship-1.c.jj 2018-08-30 19:41:13.762257530 +0200
+++ gcc/testsuite/c-c++-common/cpp/spaceship-1.c 2018-08-30 19:49:09.338386388 +0200
@@ -0,0 +1,6 @@
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11" { target c } } */
+
+#define A(x, y) x##y
+A(<=, >) /* { dg-error "does not give a valid preprocessing token" "" { target { ! c++2a } } } */
+A(<=>, >) /* { dg-error "does not give a valid preprocessing token" "" { target c++2a } } */
--- gcc/testsuite/g++.dg/cpp/spaceship-1.C.jj 2018-08-30 19:58:56.152695104 +0200
+++ gcc/testsuite/g++.dg/cpp/spaceship-1.C 2018-08-30 19:59:20.802288063 +0200
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++17_down } }
+// { dg-options "-Wno-pointer-arith" }
+
+struct X {};
+bool operator<= (X, X);
+template<bool (X, X)> struct Y {};
+Y<&operator<=> y;
+bool foo (bool (*fn) (X, X), int n) { return n+&operator<=> fn; }


        Jakub
12