Date: Sun, 08 Oct 2023 15:41:16 +0200
Am Sonntag, dem 08.10.2023 um 14:02 +0300 schrieb Timur Doumler:
> Hi Martin,
>
> I think this is just one of those cases where C and C++ have different priorities and unfortunately it is impossible to make everyone happy.
>
> In C++, context-sensitive keywords are common, and in this particular case, using context-sensitive keywords for `pre` and `post` allow us to use any identifier we want without breaking any
> existing code. The keywords `pre` and `post` have been chosen carefully and gained strong consensus (see P1344R1). Replacing them with longer, "uglier" keywords in C++ so that C can have a
> non-context-sensitive keyword that doesn't start with an underscore is a tradeoff that simply doesn't make sense for C++ and it doesn't have any realistic chance of gaining consensus in
> SG21 from my perspective.
>
> I do care about C compatibility (which is why I started that thread), but I think that using _Pre and _Post in C is a reasonable compromise, at least for now. This gives you the ability to
> #define pre _Pre for newer compilers and thus have code with Contracts shared between C and C++, while at the same time macro away Contracts entirely for backwards-compatibility with older
> compilers. Yes, the macroing away might no longer be possible with post-C++26 extensions, but even then, both code sharing between C and C++ and backwards-compatibility with older compilers
> can be achieved by wrapping the Contract annotations themselves into macros, like we do for many other features already. This isn't ideal but seems like a reasonable compromise to me. And
> you are of course free to propose a syntax for the post-C++ extensions that is more compatible with function-like macros than the solutions proposed so far – if such a paper materialises,
> we will consider it in SG21.
Hi Timur,
unfortunately, I do not have the capacity to work on alternative
solutions for C++ and then spent time advocating those in WG21.
I fully understand that WG21 may also need to consider many
other aspects in addition to C compatibility (and so does WG14),
and the outcome may be some kind of compromise.
It is, of course, useful to avoid any unnecessary divergence
where this is possible and it is useful for us to have these
discussions. So thank you for this!
I still think that C will need to adopt longer keywords later.
But I also agree that some kind of macro solution that bridges
the gaps is then sufficient for header compatibility.
There are, however, people who care much more about keeping
C and C++ as similar as possible and who might not be completely
happy about this. I think those people should step up *now*
and propose a compromise that finds full consensus in C and C++
if they care very much about this.
>
> To me, this compromise sounds doable, consistent with what we've done before for other features shared between C and C++, and still better than using [[ ... ]] which apparently in C has the
> notion of "this is token-ignorable". At least for newer compilers that know about Contracts, token-ignoring Contracts is not something that I would want to allow or encourage. Attributes in
> C are all either for enabling/disabling warnings or for giving optimisation hints to the backend. Contracts are not like that at all. They are a core language feature and there is nothing
> "optional" about them – in the sense that an implementation shouldn't be allowed to just not implement them and still be conforming.
>
> Anyway, I hope this makes sense, but if I'm missing something please let me know!
I still like to comment on this last point and why I am
not convinced by it.
First, whether a new implementation is allowed to ignore
them or not, is a matter of standardization and not of
syntax: If the standard says it can be ignored it can
be ignored and it says it cannot ignored, then it cannot
be ignored by a conforming implementation.
Second, attributes are ideally suited and would solve all
the technical issues related to backwards compatibility
we discussed here in a nice way. The would also have
no risk, as we can always invent new syntax later.
In contrast, introducing new syntax now has a huge risk
and opportunity cost.
Finally, I think from a perspective of semantics, attributes
are also an excellent fit: Contracts are annotations that
- when removed from a correct program - should not change its
semantics. For me, this makes them seem more similar to
other annotations (as expressed by attributes) than to other
language constracts. For me, the use of attributes for all
such annotations would make a lot of sense. This would be
easy to explain and teach and work with.
Best,
Martin
>
> Cheers,
> Timur
>
> > On 8 Oct 2023, at 09:17, Martin Uecker <ma.uecker_at_[hidden]> wrote:
> >
> > Am Samstag, dem 07.10.2023 um 18:35 +0300 schrieb Timur Doumler via Liaison:
> > > Right. I see.
> > >
> > > In this case you are right, P2961 as proposed for C++26 seems fully compatible with function-like-macro-ing it away in C if you so desire. The planned post-C++26 extensions are not, but
> > > we can deal with that later.
> >
> > I agree, when it is understood that the extensions
> > are problematic.
> >
> > >
> > > So it seems to me now that — possible post-C++26 extensions aside — the P2961 syntax is actually *more* backwards compatible than the P2935 (attribute-like) syntax. With P2961, you can
> > > adopt the same syntax in C using _Pre and _Post as the keywords and then do something along the lines of
> > >
> > > #if MY_COMPILER_SUPPORTS_CONTRACTS
> > > #define pre _Pre
> > > #else
> > > #define pre(...) // nothing
> > > #endif
> > >
> > > And then you can use standard Contract syntax even with an old compiler! On the other hand, with P2935 (attribute-like syntax), you can't do that, you'd have to wait for your compiler
> > > to know at least to ignore the colon inside [[ ... ]] which it doesn't currently do (all major compilers issue a parse error).
> > >
> > > @Martin: considering the above, do you have any more thoughts on this?
> >
> > There is still the issue that "pre" and "post" will collide
> > with existing code.
> >
> > And context sensitive keywords do not currently exist and
> > are also problematic. _Pre and _Post would work, but our
> > general goal is to then transition to lower case keywords
> > later (as we did already for many in C23), and I am not
> > sure this works for "pre" and "post".
> >
> > But these issues have been pointed out by others before.
> >
> > Martin
> >
> > >
> > > Cheers,
> > > Timur
> > >
> > > > On 7 Oct 2023, at 17:44, Ville Voutilainen <ville.voutilainen_at_[hidden]> wrote:
> > > >
> > > > On Sat, 7 Oct 2023 at 17:37, Ville Voutilainen
> > > > <ville.voutilainen_at_[hidden]> wrote:
> > > > > > Wait, not quite:, there is the syntax for return values in postconditions which is not a future extension – that's being proposed now:
> > > > > >
> > > > > > int f()
> > > > > > post (ret: ret >= 0);
> > > > > >
> > > > > > Is that colon in there compatible with function-like macros? Because that's not valid function call syntax at least.
> > > > >
> > > > > Of course it is, the argument list of a macro is just a token or
> > > > > multiple tokens. Thus:
> > > > >
> > > > > #define post(X)
> > > > >
> > > > > void f(int x, int y)
> > > > > post(ret: ret >= 0)
> > > > > {
> > > > > (void)x;
> > > > > (void)y;
> > > > > }
> > > > >
> > > > > https://wandbox.org/permlink/JavMNfd6kGjF9f13
> > > >
> > > > And, for what it's worth, I can make that
> > > >
> > > > post([[]]}}}][][]]]]]]}}}()();;::;;)
> > > >
> > > > which is a parentheses-balanced token sequence and thus a valid
> > > > invocation of that function-like macro,
> > > > but otherwise contains stuff that's not fathomably valid in any
> > > > hypothetical future version of C++, but the macro
> > > > slurps it just fine.
> > >
> > > _______________________________________________
> > > Liaison mailing list
> > > Liaison_at_[hidden]
> > > Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> > > Link to this post: http://lists.isocpp.org/liaison/2023/10/1294.php
> >
> Hi Martin,
>
> I think this is just one of those cases where C and C++ have different priorities and unfortunately it is impossible to make everyone happy.
>
> In C++, context-sensitive keywords are common, and in this particular case, using context-sensitive keywords for `pre` and `post` allow us to use any identifier we want without breaking any
> existing code. The keywords `pre` and `post` have been chosen carefully and gained strong consensus (see P1344R1). Replacing them with longer, "uglier" keywords in C++ so that C can have a
> non-context-sensitive keyword that doesn't start with an underscore is a tradeoff that simply doesn't make sense for C++ and it doesn't have any realistic chance of gaining consensus in
> SG21 from my perspective.
>
> I do care about C compatibility (which is why I started that thread), but I think that using _Pre and _Post in C is a reasonable compromise, at least for now. This gives you the ability to
> #define pre _Pre for newer compilers and thus have code with Contracts shared between C and C++, while at the same time macro away Contracts entirely for backwards-compatibility with older
> compilers. Yes, the macroing away might no longer be possible with post-C++26 extensions, but even then, both code sharing between C and C++ and backwards-compatibility with older compilers
> can be achieved by wrapping the Contract annotations themselves into macros, like we do for many other features already. This isn't ideal but seems like a reasonable compromise to me. And
> you are of course free to propose a syntax for the post-C++ extensions that is more compatible with function-like macros than the solutions proposed so far – if such a paper materialises,
> we will consider it in SG21.
Hi Timur,
unfortunately, I do not have the capacity to work on alternative
solutions for C++ and then spent time advocating those in WG21.
I fully understand that WG21 may also need to consider many
other aspects in addition to C compatibility (and so does WG14),
and the outcome may be some kind of compromise.
It is, of course, useful to avoid any unnecessary divergence
where this is possible and it is useful for us to have these
discussions. So thank you for this!
I still think that C will need to adopt longer keywords later.
But I also agree that some kind of macro solution that bridges
the gaps is then sufficient for header compatibility.
There are, however, people who care much more about keeping
C and C++ as similar as possible and who might not be completely
happy about this. I think those people should step up *now*
and propose a compromise that finds full consensus in C and C++
if they care very much about this.
>
> To me, this compromise sounds doable, consistent with what we've done before for other features shared between C and C++, and still better than using [[ ... ]] which apparently in C has the
> notion of "this is token-ignorable". At least for newer compilers that know about Contracts, token-ignoring Contracts is not something that I would want to allow or encourage. Attributes in
> C are all either for enabling/disabling warnings or for giving optimisation hints to the backend. Contracts are not like that at all. They are a core language feature and there is nothing
> "optional" about them – in the sense that an implementation shouldn't be allowed to just not implement them and still be conforming.
>
> Anyway, I hope this makes sense, but if I'm missing something please let me know!
I still like to comment on this last point and why I am
not convinced by it.
First, whether a new implementation is allowed to ignore
them or not, is a matter of standardization and not of
syntax: If the standard says it can be ignored it can
be ignored and it says it cannot ignored, then it cannot
be ignored by a conforming implementation.
Second, attributes are ideally suited and would solve all
the technical issues related to backwards compatibility
we discussed here in a nice way. The would also have
no risk, as we can always invent new syntax later.
In contrast, introducing new syntax now has a huge risk
and opportunity cost.
Finally, I think from a perspective of semantics, attributes
are also an excellent fit: Contracts are annotations that
- when removed from a correct program - should not change its
semantics. For me, this makes them seem more similar to
other annotations (as expressed by attributes) than to other
language constracts. For me, the use of attributes for all
such annotations would make a lot of sense. This would be
easy to explain and teach and work with.
Best,
Martin
>
> Cheers,
> Timur
>
> > On 8 Oct 2023, at 09:17, Martin Uecker <ma.uecker_at_[hidden]> wrote:
> >
> > Am Samstag, dem 07.10.2023 um 18:35 +0300 schrieb Timur Doumler via Liaison:
> > > Right. I see.
> > >
> > > In this case you are right, P2961 as proposed for C++26 seems fully compatible with function-like-macro-ing it away in C if you so desire. The planned post-C++26 extensions are not, but
> > > we can deal with that later.
> >
> > I agree, when it is understood that the extensions
> > are problematic.
> >
> > >
> > > So it seems to me now that — possible post-C++26 extensions aside — the P2961 syntax is actually *more* backwards compatible than the P2935 (attribute-like) syntax. With P2961, you can
> > > adopt the same syntax in C using _Pre and _Post as the keywords and then do something along the lines of
> > >
> > > #if MY_COMPILER_SUPPORTS_CONTRACTS
> > > #define pre _Pre
> > > #else
> > > #define pre(...) // nothing
> > > #endif
> > >
> > > And then you can use standard Contract syntax even with an old compiler! On the other hand, with P2935 (attribute-like syntax), you can't do that, you'd have to wait for your compiler
> > > to know at least to ignore the colon inside [[ ... ]] which it doesn't currently do (all major compilers issue a parse error).
> > >
> > > @Martin: considering the above, do you have any more thoughts on this?
> >
> > There is still the issue that "pre" and "post" will collide
> > with existing code.
> >
> > And context sensitive keywords do not currently exist and
> > are also problematic. _Pre and _Post would work, but our
> > general goal is to then transition to lower case keywords
> > later (as we did already for many in C23), and I am not
> > sure this works for "pre" and "post".
> >
> > But these issues have been pointed out by others before.
> >
> > Martin
> >
> > >
> > > Cheers,
> > > Timur
> > >
> > > > On 7 Oct 2023, at 17:44, Ville Voutilainen <ville.voutilainen_at_[hidden]> wrote:
> > > >
> > > > On Sat, 7 Oct 2023 at 17:37, Ville Voutilainen
> > > > <ville.voutilainen_at_[hidden]> wrote:
> > > > > > Wait, not quite:, there is the syntax for return values in postconditions which is not a future extension – that's being proposed now:
> > > > > >
> > > > > > int f()
> > > > > > post (ret: ret >= 0);
> > > > > >
> > > > > > Is that colon in there compatible with function-like macros? Because that's not valid function call syntax at least.
> > > > >
> > > > > Of course it is, the argument list of a macro is just a token or
> > > > > multiple tokens. Thus:
> > > > >
> > > > > #define post(X)
> > > > >
> > > > > void f(int x, int y)
> > > > > post(ret: ret >= 0)
> > > > > {
> > > > > (void)x;
> > > > > (void)y;
> > > > > }
> > > > >
> > > > > https://wandbox.org/permlink/JavMNfd6kGjF9f13
> > > >
> > > > And, for what it's worth, I can make that
> > > >
> > > > post([[]]}}}][][]]]]]]}}}()();;::;;)
> > > >
> > > > which is a parentheses-balanced token sequence and thus a valid
> > > > invocation of that function-like macro,
> > > > but otherwise contains stuff that's not fathomably valid in any
> > > > hypothetical future version of C++, but the macro
> > > > slurps it just fine.
> > >
> > > _______________________________________________
> > > Liaison mailing list
> > > Liaison_at_[hidden]
> > > Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> > > Link to this post: http://lists.isocpp.org/liaison/2023/10/1294.php
> >
Received on 2023-10-08 13:41:20