C++ Logo

std-discussion

Advanced search

Re: Why abandon lambda-styled captures in the latest Contracts MVP, and adopt the implicit const-ness instead?

From: Tom Honermann <tom_at_[hidden]>
Date: Tue, 9 Apr 2024 11:02:48 -0400
Support for lambda-style captures has not been abandoned; there is full
intent to continue working on it, particularly for use with
postconditions (which require a function parameter to be declared const
to be accessed; the implicit const-qualified access has no effect in a
postcondition).

Requiring capture to access any function argument in a precondition or
local variable in a contract assertion statement is unnecessary when
there is no intent to modify (a copy of) the object. The implicit
const-qualified access approach enables a convenient syntax while also
reducing the risk of unintended modifications. The implicit
const-qualified access is not intended to completely prevent
modification, it is only intended to make such modification explicit
because such intent to do so is rare. Note that mutation of a const
object remains UB (you can use const_cast on a non-const function
parameter, but if you use const_cast on a const function parameter,
mutation results in UB).

Tom.

On 4/9/24 9:31 AM, vspefs via Std-Discussion wrote:
> To whom it may concern,
>
> While reading P2900R5, I can't help but notice the implicit const-ness
> for identifiers and the tacit consent that they are regarded as const
> lvalues within condition expressions.
>
> This, of course, is a way to imply that contracts are to observe, to
> check, not to modify. However, I do think I see some problems are
> there, which may lead to human confusion on multiple levels.
>
> - People get confused by the "default" const-ness.
>
> 1. 'pre' and 'post' are keywords for contracts, which may indeed
> remind us of the original idea behind the implicit const-ness.
> However, it's common that once people begin to fill the parentheses,
> people forget about everything outside. And exactly, that's why some
> people tend to use manual prefix/postfix on each identifier to point
> out cv-qualifications, reference types and other things, which
> *tradition *now becomes inconsistent.
>
> If const-ness is to be added to the identifiers in condition
> expressions, I think a more explicit** way can be adopted, even if it
> means not doing so (attaching const-ness to identifiers) by default.
> Maybe like the const-specifier to member functions.
>
> 2. By const_cast<> and our powerful pointers, we can still modify
> the local variables and parameters. Besides, it's also open to modify
> namespace-scope or local static variables. But actually, in my
> opinion, that makes the whole 'safety' concern not safe at all.
>
> First, if the whole contracts facility is to observe, why would we
> want "such accesses are more likely to be intentionally modifying"
> (quoted from the original paper) to be modified *here*, not *anywhere
> *else?
>
> Second, it's so common that strict limitations, if not strictly
> applied, become no limitation at all. Because powerful features would
> easily be used as 'silver bullets' by someone who just wants a quick
> workaround and couldn't care less about original intentions behind
> features. If that idea lingers too long, it could easily become a
> 'legacy mis-usage'.
>
> 3. Some conceptual mazes here. As we all know, modifying a const
> value is considered to be an undefined behaviour. But what about here,
> in condition expressions, where identifiers are *regarded *as const
> lvalues? So modifying value here with some techniques, can be seen as
> an undefined behaviour 'locally', while it's legal 'globally'? Of
> course, it purely depends on how carefully one would read and
> interpret the standard, but less conceptual maze is better than more.
>
> 4. All identifiers are considered *lvalues *here. Not sure if that
> would lead to some unnecessary inconvenience, or worse, limitations.
>
> - It's just that "implicit"s shouldn't be implicit.
>
> 1. This creates burden and stress for programmers when memorizing
> and applying Contracts. The evolution of C++ in recent years is
> impressive, yet not too energy-consuming to catch up. I don't see why
> we shouldn't keep this pace and create extra burden for learners.
>
> 2. We shouldn't be creating intuition-countering syntax and
> semantics. Intuition is important in programming as it's in various
> fields. For example, most of the time, intuition works when it comes
> to thinking about value categories, like whether we should use
> std::move() here, or not.
>
> So, based on all mentioned above, I think the current MVP doesn't
> quite serve our purpose well. Instead, I'd propose the original syntax
> in P2461R1, which uses lambda-styled captures to specify the
> identifiers to be used in condition expressions. Or, I'd rather we
> totally ban modifications within condition expressions. However, I do
> agree that suitable changes can be make to improve the clarity and
> readability of our code.
>
>
> If my idea appears to be inadequate, lack of basic knowledge, or
> already answered before, please do point me out.
>
> Written on Tue, Apr 9, 2024 at 9:27 pm (UTC+8).
>
>

Received on 2024-04-09 15:02:50