C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] [isocpp-sg21] Telecon to review P2388R1 Minimum Contract Support: either Ignore or Check_and_abort

From: Ryan McDougall <mcdougall.ryan_at_[hidden]>
Date: Tue, 21 Sep 2021 09:25:16 -0700
Comments inline

On Mon, Sep 20, 2021 at 1:49 PM Aaron Ballman <aaron_at_[hidden]>
wrote:

> On Mon, Sep 20, 2021 at 12:36 PM Ryan McDougall
> <mcdougall.ryan_at_[hidden]> wrote:
> >
> > Can you help me understand the concern here -- is it that C will have to
> update its grammar to recognize this syntax as not ignorable, and they
> would rather not?
>
> I am raising a concern as a liaison with WG14 who was the one that
> standardized [[]] syntax in that committee. During those discussions,
> we had a *lot* of debate over the syntax and the semantics of the
> feature, but one of the concerns that was raised by an implementer was
> their requirement that attributes be "ignorable" as they are in C++.
> They have implementation burdens with nonignorable attributes for some
> of their implementations and they very much appreciated the discussion
> in WG21 N2761 about the design intent of when it's appropriate to use
> an attribute vs other syntax. To save people effort, a key point from
> that paper was:
>
> "After the meeting in Toronto, we added specific guidance on the
> choice of when to use an attribute to avoid misuse. There was general
> agreement that attributes should not affect the type system, and not
> change the meaning of a program regardless of whether the attribute is
> there or not."
>
> The current proposal changes the meaning of code when the contract
> attribute is not present. Further, that document gives some advice on
>

This is not true -- the narrow contract of a function exists regardless of
the notation that it is encoded with. I think this is the central
misunderstanding here, so I'll elaborate in detail.

```
int f (int x) {
  return 5 / x;
}
```

Here the contract is "x cannot be zero" -- regardless of any syntax.

This is a correct program. It is correct regardless of syntax or checking.
```
int main() {
  return f(1);
}
```

This is an incorrect program. It is incorrect regardless of syntax or
checking.
```
int main() {
  return f(0);
}
```

With no contract checking statement, the incorrect program above yields
undefined behavior.

The purpose of contract syntax is to encode "that [a] contract violation
[...] indicates a bug, which programmers intend to avoid or fix."

Which is to say that the purpose of every programmer is to generate
*correct programs*, and the existence of an incorrect program is a
temporary situation that exists for as little time as possible.

If we add a C++ **attribute** that encodes the contract, the program is
still incorrect -- regardless of whether the programmer notices (such as
via a violation handler) at all.

```
int f (int x)
[[ pre(x != 0) ]] { // <-- an attribute, can ignore
  return 5 / x;
}

int main() {
  return f(0);
}
```

Since we want to make sure the programmer is well aware of its
incorrectness, so we explicitly choose to **not** use an attribute.

```
int f (int x)
[[ pre: x != 0 ]] { // <-- NOT an attribute, can't ignore
  return 5 / x;
}

int main() {
  return f(0);
}
```

In **either case** however -- so long as the attribute is not ignored -- we
can turn on runtime checking, and have the compiler insert the moral
equivalent of

```
int f (int x) {
  assert(x != 0);
  return 5 / x;
}
```

Note that **this does not change the meaning of the program** -- it's still
either correct or incorrect depending in inputs -- contract is unchanged.
Correct programs are still correct, and incorrect programs are still
incorrect.

However for incorrect programs, we have turned potentially undefined
behavior into well defined behavior (terminate), which hopefully causes the
developer to realize there's a bug, and cause the incorrect program to be
correct again.

To repeat: the correct program's behavior **never** changed. The incorrect
program's behavior was never correct to begin with, and the only thing that
mattered was how long it took for the programmer to notice that fact.

This is a round-about way of saying "even if contract checking statements
were attributes (and they're not), it is true that they do not affect the
behavior of correct programs, and for incorrect programs the question is
ill formed".

If you're using contracts, your purpose is to find and fix incorrect
programs before they're released, and you will make certain you're doing
your development on a compiler that generates runtime checking for your
contracts.


> when it's reasonable to use an attribute vs another syntax, and one
> explicit point on when to not use an attribute is "The feature is a
> central part of the declaration that significantly affects its
> requirements/semantics" and the whole point to contracts is to
> significantly affect the requirements of a call.
>

This is not true as above:

1. Contracts exist regardless of syntax, and the purpose of having a syntax
is to detect bugs. When there are no bugs, there is no effect on the a call.
2. When there is a bug and runtime checking is turned on, the purpose is to
inform the programmer so they can remove the bug ASAP, and make the program
correct again.
3. When runtime checking is not turned on, the contract can still be
checked by static analysis, which has no effect on the call. This is a
major use case.


> I mentioned earlier in the thread how they indicated their
> implementations were going to work (eat tokens between [[ and ]] with
> a generic diagnostic), and the syntax used for contracts would cause a
> problem for that sort of implementation strategy. So I'm raising that
> issue because I'm concerned that the non-ignorable nature of this
> attribute-like syntax is going to generate pushback, as happened
> during C++20. I can try to go into more detail of how I understood the
> implementer's concerns, but I don't think that needs relitigation. The
> concerns were sufficient to cause WG14 to request changes to the
> proposal and so I think we should trust the concerns are valid.
>

I'm unclear what the reservation is. With the C++20 syntax (re-used here),
that same implementer could not "eat tokens between [[ and ]]" -- but would
instead need to "check if there's a colon, and then eat tokens between [[
and ]]". I'm not sure that's a high burden.

If that implementer either doesn't want to support contracts, or for
performance reasons on their platform cannot, then correct programs will
still be correct programs -- just incorrect programs will have one less
diagnostic tool for discovering bugs. A non-compliant implementation is
perfectly workable.


> (Additionally, I have personal reservations about the syntax chosen,
> but I want to keep that discussion separate so there's hopefully less
> confusion about what's a liaison concern and what's not.)
>
> > On Mon, Sep 20, 2021 at 8:02 AM Aaron Ballman via SG21 <
> sg21_at_[hidden]> wrote:
> >>
> >> On Mon, Sep 20, 2021 at 10:36 AM John Spicer <jhs_at_[hidden]> wrote:
> >> >
> >> > The contracts syntax is intentionally “attribute-like” but “not
> actually an attribute”, which allows a compiler to treat those differently.
> >>
> >> Never have I ever found a user who thinks that explanation holds
> >> water. As an implementer, I've asked dozens of people, and they
> >> uniformly say "stuff between [[]] is an attribute", and indeed, the
> >> original contracts proposal even calls them "contract attributes" and
> >> lists them under the Attributes section of the standard.
> >>
> >> (This is treading well-trodden ground we don't need to re-cover here.)
> >>
> >> > But the syntax difference is very subtle and a different that a
> compiler that does not support attributes would be unlikely to check for.
> >> >
> >> > As an example:
> >> >
> >> > [[something x]]
> >> > [[something(x)]]
> >> >
> >> > The first is an invalid attribute but we could potentially decide to
> make it a contract, while the second is a valid attribute.
> >> >
> >> > So, C++ is saying that the syntax of the stuff inside “[[ ]]” matters
> in the contract vs. attribute decision.
> >> >
> >> > I believe that is intentional so that older C++ compilers that
> support attribute but not contracts will probably ignore them.
> >> >
> >> > I think that also means that unless a C compiler does syntax checking
> on unrecognized attributes, there should not be an issue.
> >>
> >> There are compilers for which the implementation strategy for all
> >> attributes is to note the [[ that opens an attribute specifier, eat
> >> all balanced tokens up to the closing ]], and diagnose the entire bit
> >> as "attribute ignored" (as a warning). You cannot do that with
> >> contracts because a correct program does not remain correct when the
> >> contract is ignored. A program can correctly rely on the contract
> >> violation handler executing, and that's not the case with this
> >> implementation strategy.
> >
> >
> > A correct program is correct regardless of whether its contract is doing
> runtime checking. Are you saying that an *incorrect* program cannot rely on
> its violation handler running when it is compiled as a C program? Would
> that not mean that all C programs have their contract checking turned off?
> >
> >> > All of that said, making progress on contracts is an important and
> also difficult process, and I don’t want to have to guess which other
> groups might have concerns about our direction.
> >> >
> >> > So, if SG21’s work is of concern to SG22, please make sure that
> someone is monitoring and or attending our meetings.
> >>
> >> I can certainly ask SG22 members to attend SG21 meetings if they're
> >> interested in the topic. However, it's a pretty tall order to expect
> >> someone to sign up to fight this level of apathy for the SG22 mandate
> >> when the SG21 answer to "I want to Specify contracts in a way
> >> standardizable as part of the C language" is 3:1 saying it's not
> >> important.
> >>
> >> ~Aaron
> >
> >
> > I think everyone wants the C/C++ compatibility story to be as good as
> possible, but can you outline for us the actual damage?
> >
> > I may be misunderstanding, but to me it seems like you'd rather C++ wait
> to get a harmonized contract syntax, rather than C++ users get a syntax for
> C++23 and force C to catch up?
>
> As a liaison activity, I want to ensure that C++ picks a contract
> syntax that is as likely to get potential (eventual) adoption into C
> as we can find. My fear is that we'll pick the currently proposed
> syntax and that will effectively either prevent adoption into C (too
> unpalatable, we'd rather have nothing) or will be adopted with
> incompatible syntax (WG21 goes with [[]] and WG14 goes with
> _Pre/_Post), and then users are the ones who lose.
>
> If SG21 thinks this is the syntax that should be standardized, that's
> fine, but then please get some explicit buy-in with WG14 on it because
> this is shared design space. WG21 makes this request from time to
> time. The latest example I can think of is EWG explicitly requesting
> input from WG14 on delimited escape sequence syntax before they felt
> comfortable with moving forward on P2290R1 for C++23. They didn't
> require WG14 to adopt the same feature at the same time, or even adopt
> the feature at all. They mostly wanted to know that if WG14 was going
> to adopt something to perform that functionality, the syntax chosen by
> WG21 was not known to be a nonstarter in WG14. I think contracts are
> sufficiently important and the syntax chosen is known to be
> potentially troublesome enough to warrant the same sort of
> consideration.
>
> ~Aaron
>
> >
> >>
> >> >
> >> > Thanks,
> >> >
> >> > John.
> >> >
> >> > > On Sep 20, 2021, at 10:12 AM, Aaron Ballman <aaron_at_[hidden]>
> wrote:
> >> > >
> >> > > On Mon, Sep 20, 2021 at 9:54 AM John Spicer via SG21
> >> > > <sg21_at_[hidden]> wrote:
> >> > >>
> >> > >> My personal opinion is that there are SG22 people involved in SG21
> and the should bring forward their concerns they might have.
> >> > >
> >> > > FWIW, I raised some concerns I had when we were early in the process
> >> > > of discovering people's concerns. I've since had to step back from
> >> > > SG21 participation and haven't been able to follow along, but P1995
> >> > > did not give me much hope.
> >> > >
> >> > >
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1995r0.html#cdev.ignorable
> >> > > As a C Developer
> >> > > In order to Write contracts on my functions
> >> > > I want to Make all contract semantics optional (so as not to change
> >> > > WG14-N2385 6.7.11 p2)
> >> > >
> >> > > Must Have: 3, Nice to Have: 3, Not Important: 23 , No Answer: 1
> >> > >
> >> > >
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1995r0.html#cdev.contracts
> >> > > As a C Developer
> >> > > In order to Write contracts on my functions
> >> > > I want to Specify contracts in a way standardizable as part of the
> C language
> >> > >
> >> > > Must Have: 2, Nice to Have: 6, Not Important: 21 , No Answer: 1
> >> > >
> >> > > It seems to me like there's a reason for SG22 to be involved given
> >> > > that C has the same [[]] syntax that C++ has and likely has opinions
> >> > > on designs in that space that are incompatible with their
> >> > > expectations.
> >> > >
> >> > >> The authors have already been working on wording.
> >> > >>
> >> > >> IMO, the SG22 impact is not any greater than it was for the C++20
> contracts proposal, so if they didn’t have problems with that, they
> shouldn’t have concerns now.
> >> > >
> >> > > SG22 was formed after C++20, so there was no official study group
> >> > > stance on the proposal at that time. However, compatibility with C
> was
> >> > > one of the reasons I voted strongly against contracts in C++20 and
> >> > > helped push me to form SG22 in the first place. My (admittedly fast
> >> > > and not thorough) reading of P2388R0 has the same concerns as
> before.
> >> > > I think getting the SG22 perspective would be useful in hopefully
> >> > > avoiding future NB comments, especially because those can arrive
> >> > > through other committees than WG21.
> >> > >
> >> > > ~Aaron
> >> > >
> >> > >>
> >> > >> John.
> >> > >>
> >> > >>> On Sep 20, 2021, at 9:18 AM, Peter Brett <pbrett_at_[hidden]>
> wrote:
> >> > >>>
> >> > >>> Hi all,
> >> > >>>
> >> > >>> Please at least get outline approval from SG22 for the syntax
> before proceeding to spend time writing wording.
> >> > >>>
> >> > >>> Best regards,
> >> > >>>
> >> > >>> Peter
> >> > >>>
> >> > >>>> -----Original Message-----
> >> > >>>> From: SG21 <sg21-bounces_at_[hidden]> On Behalf Of John
> Spicer via SG21
> >> > >>>> Sent: 13 September 2021 11:06
> >> > >>>> To: SG21 - Contracts <sg21_at_[hidden]>
> >> > >>>> Cc: John Spicer <jhs_at_[hidden]>
> >> > >>>> Subject: [isocpp-sg21] Telecon to review P2388R1 Minimum
> Contract Support:
> >> > >>>> either Ignore or Check_and_abort
> >> > >>>>
> >> > >>>> EXTERNAL MAIL
> >> > >>>>
> >> > >>>>
> >> > >>>> We’d like to have a telecon to discuss this paper.
> >> > >>>>
> >> > >>>> We are thinking about either Tuesday 9/21, 9/28, or 10/5 at 8 AM
> Pacific
> >> > >>>> time.
> >> > >>>>
> >> > >>>> Please indicate your preference at this Doodle page:
> >> > >>>>
> >> > >>>>
> https://urldefense.com/v3/__https://doodle.com/meeting/participate/id/mbkZ7Z
> >> > >>>> 6a__;!!EHscmS1ygiU1lA!S7mTfbNuJm-ECRyonHAxUX-
> >> > >>>> WCICkzN9Bo8PvtmHnnslnt0YaN8QUMTi3OMtKqw$
> >> > >>>>
> >> > >>>> Thanks,
> >> > >>>>
> >> > >>>> John Spicer
> >> > >>>> SG21 Contracts Chair
> >> > >>>> _______________________________________________
> >> > >>>> SG21 mailing list
> >> > >>>> SG21_at_[hidden]
> >> > >>>> Subscription:
> >> > >>>>
> https://urldefense.com/v3/__https://lists.isocpp.org/mailman/listinfo.cgi/sg
> >> > >>>> 21__;!!EHscmS1ygiU1lA!S7mTfbNuJm-ECRyonHAxUX-
> >> > >>>> WCICkzN9Bo8PvtmHnnslnt0YaN8QUMThM7kehDA$
> >> > >>>> Searchable archives:
> >> > >>>>
> https://urldefense.com/v3/__http://lists.isocpp.org/sg21/2021/09/index.php__
> >> > >>>> ;!!EHscmS1ygiU1lA!S7mTfbNuJm-ECRyonHAxUX-
> >> > >>>> WCICkzN9Bo8PvtmHnnslnt0YaN8QUMTi7_Om32Q$
> >> > >>
> >> > >> _______________________________________________
> >> > >> SG21 mailing list
> >> > >> SG21_at_[hidden]
> >> > >> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> >> > >> Link to this post: http://lists.isocpp.org/sg21/2021/09/1168.php
> >> >
> >> _______________________________________________
> >> SG21 mailing list
> >> SG21_at_[hidden]
> >> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/sg21
> >> Link to this post: http://lists.isocpp.org/sg21/2021/09/1180.php
>

Received on 2021-09-21 11:25:34