C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] P2961R1 syntax for Contracts: viable for C?

From: Aaron Ballman <aaron_at_[hidden]>
Date: Thu, 5 Oct 2023 11:09:37 -0400
On Thu, Oct 5, 2023 at 7:58 AM Timur Doumler via Liaison
<liaison_at_[hidden]> wrote:
>
> Hello SG22,
>
> In SG21 (Contracts), we have been discussing the syntax for preconditions, postconditions, and assertions which will be part of the new Contracts facility we're designing for C++26. We currently have two syntax proposals on the table – we have not yet decided which one we prefer.
>
> One is the attribute-like syntax which you might have already seen (see P2935R3). With this syntax, a function declaration with a precondition and a postcondition looks like this:
>
> int f(int i)
> [[ pre: i >= 0 ]]
> [[ post r: r > i ]];
>
> The other is a newer proposal that seeks to eliminate the various issues with attribute-like syntax we discovered (see P2961R1, which I am co-authoring together with Jens Maurer, in Cc). The P2961R1 syntax looks like this:
>
> void f(int i)
> pre (i >= 0)
> post (r: r > i);
>
> At the last SG21 telecon, the question has been raised whether the P2961R1 syntax would be compatible with C, in case C wishes to standardise a Contracts facility consistent with the C++ one. As the main paper author of P2961R1, I was directed to ask WG14 about their opinion and report back to SG21.
>
> However, I have been informed by Ville (in Cc) that WG14 is currently doing a ballot, that the WG14 Convener is adamant about having as little as possible technical discussion during a ballot, and that discussing a future proposal on the WG14 reflector would therefore be inappropriate at this time.
>
> So, if you don't mind, I'm going to try my luck with SG22 instead. Do any of you folks have any desire to standardise Contracts for C, to have a syntax for this that looks like the C++ one, and do you have any technical concerns about the syntax proposed in P2961R1?
>
> Any and all feedback would be greatly appreciated.

Thank you for reaching out!

I am personally *very* motivated to see Contracts get into C; I think
the functionality is incredibly important for a whole host of reasons
that I probably don't need to convince you of. :-D I really appreciate
all efforts to come up with syntax & semantics that can work for both
C and C++ because I would love to get to a day where the OS headers
and C standard library headers can provide contracts that the STL can
take advantage of as well. Getting as much of the source code stack to
support contracts as possible seems like a good goal to strive for.

The syntax that looks like `[[ pre: expr ]]` is a problem in C
currently. [[ always introduces an attribute specifier list currently,
and we have an allowance for implementations to eat balanced tokens
between the double square brackets. While it may be possible to change
this rule, it should be noted that the rule was introduced at the
request of several implementers of C and the decision was recently
reaffirmed by the committee during NB comment resolution for C23, so I
would expect that to be contentious. IMO, even in C++ only, claiming
that it's not an attribute because of the presence of a single colon
is not compelling rationale to me -- users already understand that
anything between [[]] is an attribute and trying to change that to be
"could be an attribute or it could be something entirely different
from attributes" is going to be confusing and cause problems in
practice.

The syntax that looks like `pre (i >= 0)` is slightly problematic in C
in that it's using an unreserved identifier. However, I think that's
pretty easy to work around by introducing it as `_Pre` in C and
providing something like a `<stdcontracts.h>` with a macro so you can
get the `pre` spelling in header code shared between C and C++. Then,
10+ years later, we can deprecate the ugly reserved keyword in C use
and start using the prettier keyword. (We did this in C23 with
numerous earlier-C keywords like `_Bool`, `_Alignas`, `_Thread_local`,
etc.) C doesn't really have the notion of conditional keywords, so I
don't think that will be an option for us (especially because we'd
still have to worry about macros named `pre`:
https://sourcegraph.com/search?q=context:global+%28%23define+pre%29%5B+%5Ct%5D%2B&patternType=regexp&case=yes&sm=1&groupBy=repo
and https://sourcegraph.com/search?q=context:global+%28%23define+post%29%5B+%5Ct%5D%2B&patternType=regexp&case=yes&sm=1&groupBy=repo
show there are such uses in the wild).

Because contracts are not intended to be an optional feature an
implementation can support at its discretion, I greatly prefer the
syntactic direction from P2961R1 over the syntax from P2935R3. Even in
C++, I think it's a superior way to surface the functionality because
it doesn't attempt to redefine existing syntax for new,
similar-but-not-actually-the-same kinds of functionality.

~Aaron

>
> Thanks,
> Timur
> _______________________________________________
> Liaison mailing list
> Liaison_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> Searchable archives: http://lists.isocpp.org/liaison/2023/10/index.php

Received on 2023-10-05 15:09:51