C++ Logo

std-proposals

Advanced search

Re: [std-proposals] lambda capture rules are too simplistic

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sat, 1 Oct 2022 09:56:40 -0400
On Sat, Oct 1, 2022 at 8:42 AM blacktea hamburger via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
> But for non-generic lambdas, there should be no additional capture. Such
> as:
>
> const int n = 1;
> [=] {int arr[n];};
>
>
This lambda doesn't capture anything. `n` is not being odr-used here. You
can verify this using `sizeof`:
    const int n = 1;
    auto lam = [=] { int arr[n]; };
    static_assert(sizeof(lam) == 1);

The only time a capture is needed is when it must be materialized — i.e.
when it is odr-used such that a definition is required — i.e. when
its address is taken such that it needs a memory address at runtime.
Compare:

    void f(int);
    auto flam = [=] { f(n); };
    static_assert(sizeof(flam) == 1);

    void g(const int&);
    auto glam = [=] { g(n); };
    static_assert(sizeof(glam) == 4);

Before asking for a problem to be fixed, it is always good to *try your
code on a compiler* and see if there is a problem at all. You can't
understand C++ in a vacuum just by reading PDFs; you have to fiddle around
with the language in practice to find out whether
the-things-you-think-are-problems-on-paper are actually problems, or if
you've just misunderstood what the paper was saying.

–Arthur



> On Sun, Sep 25, 2022 at 11:19 PM Edward Catmur <ecatmur_at_[hidden]>
> wrote:
>
>> On Sun, 25 Sept 2022 at 15:22, Edward Catmur <ecatmur_at_[hidden]>
>> wrote:
>>
>>> What about the `might_use` problem? That wouldn't be solved by your
>>> proposed refinement.
>>>
>>
>> Sorry, realized I'm talking nonsense here.
>>
>> Still, if I understand correctly, your proposed rule would be that a
>> default capture captures a variable if either (a) it is odr-used, or (b) it
>> is used in evaluated context within a branch of a constexpr if whose
>> condition is dependent on a lambda template parameter. So, for example, in
>>
>> auto f = [](auto a) {
>> int const i = 10;
>> auto g = [=] { int arr[i]; };
>> if constexpr (sizeof(a) == 1)
>> auto h = [=] { int arr[i]; };
>> };
>>
>> g would not capture i, but h would. Isn't that liable to be somewhat
>> confusing?
>>
>> On Sun, 25 Sep 2022, 09:11 blacktea hamburger via Std-Proposals, <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> P0588R0 <https://wg21.link/P0588R0> contains the rationale explaining
>>>> why the rules for implicit capture were changed in order to capture some
>>>> variables that are not going to be odr-used anyway.
>>>>
>>>> However, it makes the rules too simplistic.
>>>>
>>>> For non-generic lambda, the paper says "Note that we propose applying
>>>> this treatment uniformly to both generic and non-generic lambdas (this is
>>>> not essential to the proposal, but seems to give a more consistent language
>>>> rule)." This consistency is useless. It does ease the workload for
>>>> some language-lawyers, but the impact on the average developers is
>>>> redundant captures.
>>>>
>>>> For generic lambda, the rules can only apply to expressions in
>>>> constexpr-if, and the condition of it depends on a generic lambda parameter.
>>>>
>>>> This is enough to solve the problem to be solved in the paper.
>>>> --
>>>> Std-Proposals mailing list
>>>> Std-Proposals_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>>
>>> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2022-10-01 13:56:51