c++ - "Variable shadowed"lambda 中的警告(未捕获时)

标签 c++ gcc lambda compiler-warnings

让我们考虑一下这段代码:

int main()
{
    int a = 1;

    auto f1 = [a]() {
        int a = 10;
        return a;
    };

    auto f2 = []() {
        int a = 100;
        return a;
    };

    return a + f1() + f2();
}
使用标志时 -Wshadow使用 gcc(在 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 在这里是否有点过于严格?

最佳答案

你是对的, lambda a没有阴影main::a因为 main::a未在 lambda 中捕获,因此不在那里的范围内。
但是我想到了影子警告的目的是什么:避免程序员混淆。如果一个很长的代码体,如果程序员看到外部声明,但没有看到内部声明,他或她可能会错误地认为内部变量的使用是指外部变量。这种可能的混淆在这里仍然适用,即使该变量在技术上不会影响外部变量。
我不知道这是警告的意图还是错误。或者即使这是一个足够令人信服的理由来发出警告,即使是措辞不同的警告。阴影警告无论如何都是有问题的。你可以找到很多关于影子警告的讨论和错误报告,即使技术上正确也被认为是有害的。

关于c++ - "Variable shadowed"lambda 中的警告(未捕获时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66404751/

相关文章:

c# - lambda 表达式的对象初始化器/构造函数自引用

c++ - C++/CLI 中的值类

c - 当我想要一个共享库时,GCC 输出一个可执行的 ELF 文件

c - C 中的二进制加法,来自数组

c++ - 从通用 lambda 调用 `this` 成员函数 - clang vs gcc

c# - LINQ 表达式返回属性值?

c++ - C++ 派生类中的 this 值

c++ - 螺旋迭代

c++ - 无法在 qt creator (linux) 上链接共享库

c - MinGW gcc 与 linux gcc 可执行文件大小