"Variable shadowed" lambda 中的警告(未捕获时)
"Variable shadowed" warning in lambda (when not captured)
让我们考虑一下这段代码:
int main()
{
int a = 1;
auto f1 = [a]() {
int a = 10;
return a;
};
auto f2 = []() {
int a = 100;
return a;
};
return a + f1() + f2();
}
在 gcc 中使用标志 -Wshadow
时(在 10.2 上测试),我们收到以下警告:
<source>:26:13: warning: declaration of 'a' shadows a lambda capture [-Wshadow]
6 | int a = 10;
<source>:21:13: warning: declaration of 'a' shadows a previous local [-Wshadow]
11 | int a = 100;
我理解第一种情况,我们明确捕获 a
,因此隐藏了原始本地。然而,第二种情况很有趣,因为如果我们删除声明 int a = 100;
,我们会得到一个编译错误 (= error: 'a' is not captured: return a;
)。这不是“证明”声明与原始本地声明不在同一范围内,因此我们实际上并没有隐藏任何东西吗?因此我的问题是,警告(对于第二种情况)是否确实有效,或者 gcc 在这里是否有点过于严格?
Doesn't that "prove" that the declaration is not in the same scope as the original local, and thus we are not actually shadowing anything?
没错。外部 a
不在范围内。您在第二个示例中的声明没有隐藏任何内容。
Hence my question, whether the warning (for the second case) is indeed valid, or whether gcc is being a bit too strict here?
除了如果您将变量命名为比 a
.
你是对的,lambda a
不会影响 main::a
因为 main::a
没有在 lambda 中捕获,因此不在范围内。
不过我想想影子警告的目的是什么:避免程序员混淆。如果代码很长,如果程序员看到了外部声明,但没有看到内部声明,他或她可能会错误地认为内部变量的使用是指外部变量。这种可能的混淆在这里仍然适用,即使变量在技术上没有遮蔽外部变量。
我不知道这是警告的意图还是错误。或者即使这是一个足够令人信服的理由来发出警告,甚至是措辞不同的警告。阴影警告无论如何都是有问题的。您可以找到很多关于影子警告的讨论和错误报告,即使技术上正确也被认为是有害的。
让我们考虑一下这段代码:
int main()
{
int a = 1;
auto f1 = [a]() {
int a = 10;
return a;
};
auto f2 = []() {
int a = 100;
return a;
};
return a + f1() + f2();
}
在 gcc 中使用标志 -Wshadow
时(在 10.2 上测试),我们收到以下警告:
<source>:26:13: warning: declaration of 'a' shadows a lambda capture [-Wshadow]
6 | int a = 10;
<source>:21:13: warning: declaration of 'a' shadows a previous local [-Wshadow]
11 | int a = 100;
我理解第一种情况,我们明确捕获 a
,因此隐藏了原始本地。然而,第二种情况很有趣,因为如果我们删除声明 int a = 100;
,我们会得到一个编译错误 (= error: 'a' is not captured: return a;
)。这不是“证明”声明与原始本地声明不在同一范围内,因此我们实际上并没有隐藏任何东西吗?因此我的问题是,警告(对于第二种情况)是否确实有效,或者 gcc 在这里是否有点过于严格?
Doesn't that "prove" that the declaration is not in the same scope as the original local, and thus we are not actually shadowing anything?
没错。外部 a
不在范围内。您在第二个示例中的声明没有隐藏任何内容。
Hence my question, whether the warning (for the second case) is indeed valid, or whether gcc is being a bit too strict here?
除了如果您将变量命名为比 a
.
你是对的,lambda a
不会影响 main::a
因为 main::a
没有在 lambda 中捕获,因此不在范围内。
不过我想想影子警告的目的是什么:避免程序员混淆。如果代码很长,如果程序员看到了外部声明,但没有看到内部声明,他或她可能会错误地认为内部变量的使用是指外部变量。这种可能的混淆在这里仍然适用,即使变量在技术上没有遮蔽外部变量。
我不知道这是警告的意图还是错误。或者即使这是一个足够令人信服的理由来发出警告,甚至是措辞不同的警告。阴影警告无论如何都是有问题的。您可以找到很多关于影子警告的讨论和错误报告,即使技术上正确也被认为是有害的。