C++ Logo

std-discussion

Advanced search

Re: Possible defect: unneeded const in lambda capture

From: Brian Bi <bbi5291_at_[hidden]>
Date: Thu, 29 Aug 2019 10:33:25 -0500
On Thu, Aug 29, 2019 at 9:29 AM Roman Odaisky via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> Lambda captures in the code
>
> X const cx;
> X const& cr = cx;
> auto lambda = [cx, cr](){};
>
> are governed by C++17 8.1.5.2.10 and N4830 7.5.5.2.10, which read, in part:
>
> The type of such a data member is the referenced type if the entity is
> a
> reference to an object, an lvalue reference to the referenced function
> type if the entity is a reference to a function, or the type of the
> corresponding captured entity otherwise.
>
> This causes the members of the lambda object corresponding to the captures
> to
> be of type X const. This is undesirable for the following reasons:
>
> 1. This causes the move constructor of the lambda to call the copy
> constructor
> of X for the const members.
> 2. This goes contrary to the rules of auto var{expr} (that don’t propagate
> constness unless explicitly specified) and introduces a discrepancy where
> [x](){} and [x{x}](){} do not mean the same thing.
> 3. This does not provide any kind of security or const correctness because
> the
> operator() is const anyway unless the lambda is explicitly marked as
> mutable,
> so all by-copy captures are constant expressions regardless of cv-
> qualifications of the original variables.
>
> Severity:
>
> Minor. Causes unneeded copies when passing lambdas around, particularly if
> it‘s an async I/O callback that stores a bunch of data to be sent at a
> later
> point. Most likely occurrence is when capturing function arguments passed
> by
> const reference, or when a const object is passed by forwarding reference.
>
> Suggested resolution:
>
> rewrite the quoted part of 7.5.5.2.10 to (additions in caps):
>
> The type of such a data member is the CV-UNQUALIFIED referenced type if
> the entity is a reference to an object, an lvalue reference to the
> referenced function type if the entity is a reference to a function, or
> the CV-UNQUALIFIED type of the corresponding captured entity otherwise.
>
> Impact on existing code:
>
> Most likely unnoticeable, primarily due to item 3 above. Would cause some
> members of mutable lambdas to stop being const expressions. Would cause
> move
> constructors to be utilized in place of copy constructors in some cases.
>
> Notes:
>
> Please correct me if there’s a better way in standardese to denote the
> removal
> of top-level cv-qualifiers. As written, the clause also mandates
> preservation
> of volatile, which makes even less sense than preservation of const.
>
> --
> WBR
> Roman.
>
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>

See
https://groups.google.com/a/isocpp.org/d/msg/std-discussion/FAb7nRfmU3I/U7dcZT-MCQAJ

-- 
*Brian Bi*

Received on 2019-08-29 10:35:42