[英]Nested lambda capture of variable gives incorrect warning
我正在使用嵌套的 lambda 来浏览一些数据。
外层lambda做一些处理,然后调用内层lambda。
我收到以下警告:
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; }
该代码使用嵌套的 lambda 调用。 以下代码将在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>();
}
如果只使用一个 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>();
}
我在 MacOS 上使用 clang 14,但为了在 Godbolt 中重现警告,我需要 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
为什么使用嵌套 lambda 会收到此警告?
我可以抑制警告吗?
或者有没有办法在仍然使用嵌套 lambdas 的同时摆脱警告?
这是在此提交中修复的编译器错误: https://github.com/llvm/llvm-project/commit/f7007c570a216c0fa87b863733a1011bdb2ff9ca 。
如您所见,提交位于 clang 14 中,特别是在标签llvmorg-14.0.0-rc2
和llvmorg-14.0.0-rc3
。 因此,警告不会出现在带有 clang 14 的 Godbolt 上,但出现在 clang 13 上是有道理的,我猜你机器上的版本不是最新的 clang14。
不幸的是,这个警告似乎没有附加任何标志。 如果您无法升级,我认为在代码中抑制它的唯一方法是使用-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>();
}
您当然可以使用-Wno-everything
或-w
进行编译,但这通常是个坏主意。
至于为什么你会收到这个警告......我从查看提交的猜测是附加条件cast<CXXRecordDecl>(D)->getTemplateDepth() > TemplateArgs.getNumRetainedOuterLevels()
使得 clang 的某些部分正确地将PickVarAtRandom
视为本地,它以某种方式解决了警告。 也许您可以在这里找到更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.