简体   繁体   中英

Nested lambda capture of variable gives incorrect warning

I'm using a nested lambda to walk through some data.
The outer lambda does some processing and then calls the inner lambda.

I get the following warning:

x86-64 clang 13.0.1 - 2629ms (104630B) ~1800 lines filtered

    Output of x86-64 clang 13.0.1 (Compiler #1)

<source>:9:34: warning: class '' does not declare any constructor to initialize its non-modifiable members
    const auto PickVarAtRandom = [&]<bool SATvar> {
                                 ^
<source>:9:34: note: in instantiation of member class '' requested here
<source>:18:41: note: in instantiation of function template specialization 'main()::(anonymous class)::operator()<true>' requested here
    const auto result = doPick.template operator()<true>();
                                        ^
<source>:10:13: note: reference member '' will never be initialized
        if (Length > 50) { printf("hallo"); return false; }

The code uses a nested lambda call. The following code will reproduce the issue in Godbolt .

#include <stdlib.h>
#include <stdio.h>


int main() {
    const auto Length = rand() % 2;

    //warning: class '' does not declare a constructor ...
    //                           V
    const auto PickVarAtRandom = [&]<bool SATvar> {
        if (Length > 0) { printf("one  %i", Length); return false; }
        else            { printf("zero %i", Length); }
        return true;
    };

    const auto doPick = [&]<bool SATvar>() {
        return PickVarAtRandom.template operator()<SATvar>();
    };

    const auto result = doPick.template operator()<true>();
}

The error goes away if just use a single lambda:

//no warning
#include <stdlib.h>
#include <stdio.h>

int main() {
    const auto Length = rand() % 100;

    const auto PickVarAtRandom = [&]<bool SATvar> {
        if (Length > 50) { printf("hallo"); return false; }
        return true;
    };

 
    const auto result = PickVarAtRandom.template operator()<true>();
}

I'm using clang 14 on MacOS, but in order to reproduce the warning in godbolt I need to select clang 13.

clang++ --version
Apple clang version 14.0.0 (clang-1400.0.29.102)
Target: arm64-apple-darwin21.6.0
Thread model: posix

Why do I get this warning with nested lambdas?
Can I suppress the warning?
Or is there a way to get rid of the warning whilst still using nested lambdas?

This is probably a bug from clang, as neither gcc nor a more recent version (>13) of clang gives this warning with -std=c++20 .

Can I suppress the warning?

Yes.

See on Godbolt .

It's a compiler bug that was fixed in this commit: https://github.com/llvm/llvm-project/commit/f7007c570a216c0fa87b863733a1011bdb2ff9ca .

As you can see, the commit is in clang 14, specifically between the tags llvmorg-14.0.0-rc2 and llvmorg-14.0.0-rc3 . So it makes sense that the warning does not appear on godbolt with clang 14 but does with clang 13, and I guess the version on your machine is not the most recent clang 14.

Unfortunately, there does not seem to be any flag attached to this warning. If you cannot upgrade, I think the only way to suppress it in code is with a pragma for -Weverything :

#include <stdlib.h>
#include <stdio.h>

int main() {
    const auto Length = rand() % 2;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weverything"
    const auto PickVarAtRandom = [&]<bool SATvar> {
#pragma GCC diagnostic pop
        if (Length > 0) { printf("one  %i", Length); return false; }
        else            { printf("zero %i", Length); }
        return true;
    };

    const auto doPick = [&]<bool SATvar>() {
        return PickVarAtRandom.template operator()<SATvar>();
    };

    const auto result = doPick.template operator()<true>();
}

godbolt

You can of course compile with -Wno-everything or -w , but that's a bad idea in general.

As for why you get this warning... my guess from looking at the commit is that the additional condition cast<CXXRecordDecl>(D)->getTemplateDepth() > TemplateArgs.getNumRetainedOuterLevels() makes some part of clang correctly treat PickVarAtRandom as local, which somehow solves the warning. Perhaps you can find more info in here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM