C++ Logo


Advanced search

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

From: Timur Doumler <cpp_at_[hidden]>
Date: Fri, 6 Oct 2023 16:09:26 +0300
Hi Martin,

> On 6 Oct 2023, at 08:31, Martin Uecker <ma.uecker_at_[hidden]> wrote:
> Am Freitag, dem 06.10.2023 um 02:02 +0300 schrieb Ville Voutilainen:
>> On Thu, 5 Oct 2023 at 20:50, Martin Uecker via Liaison
>> <liaison_at_[hidden]> wrote:
>>>> WG21 does not want contract annotations to be ignorable in the same
>>>> way as attributes (both in terms of allowing an implementation to not
>>>> support contracts and in terms of not allowing syntactic errors in the
>>>> arguments to the contract), so that would be a very poor fit.
>>> Ah, right, I forgot that this was a design goal.
>>> (The problem is that this will make it much harder for C projects
>>> to usefully adopt it.)
>> WG14 doesn't necessarily need to set that design goal for itself even
>> if WG21 might. It's unclear to me whether
>> that design goal is the right choice for the ecosystem of C.
> To be honest, I think it is a mistake also for C++. I believe
> that even for C++ people will end up trying to introduce this into
> existing code and then are forced to make it ignorable by wrapping it
> into #ifdef or macros. The end result would neither be nice
> nor ignorable.

There is a reason for this design goal. Contracts in C++ cannot be token-ignorable, because that would mean that the entities inside the contract predicate are sometimes parsed and odr-used, but sometimes not parsed and odr-used, and in C++ we have SFINAE so we can branch on whether an entity is odr-used. And an explicit goal of Contracts – the main purpose of which is to detect bugs – is that you should never be able to branch on whether a contract is checked or ignored, because then you could have a bug that cannot be detected by a Contract check – the bug is there when Contracts are off, but as soon as you switch them on to find the bug, your program takes a different branch where the bug is not present, and the bug disappears. We want to make this impossible by design.

Therefore you won't be able to do with C++ Contracts what you can do with macro assert in <cassert> today: define NDEBUG and have all the assert macros token-ignored. We want to explicitly ban that case. You will be able to turn the actual runtime check off, so if you have `pre(expr)`, then `expr` won't be evaluated (for example in Release mode), but you won't be able to turn off the fact that `expr` is still parsed and odr-used.

I'm not sure if the term "odr-use" makes any sense in C but I hope you still know what I mean. The gist is that Contracts in C++ are not, and never will be, token-ignorable.

So if you're telling me that in C, [[ ... ]] is token ignorable, then that means that we cannot use the [[ ... ]] syntax for Contracts, unless you're OK with Contracts behaving differently in C and C++ in the sense that they can be token-ignored in C but not in C++.

Please let me know if any of the above isn't clear, I would really like to make sure that we're on the same page here.


Received on 2023-10-06 13:09:31