首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当C++ lambda表达式具有大量引用捕获时,未命名函数对象的大小就会变大。

当C++ lambda表达式具有大量引用捕获时,未命名函数对象的大小就会变大。
EN

Stack Overflow用户
提问于 2014-04-18 07:32:31
回答 3查看 1.6K关注 0票数 6

以下代码:

代码语言:javascript
运行
复制
int main() {
    int a, b, c, d, e, f, g;
    auto func = [&](){cout << a << b << c << d << e << f << g << endl;};
    cout << sizeof(func) << endl;
    return 0;
}

g++ 4.8.2编译的输出56

由于所有局部变量都存储在同一个堆栈帧中,因此记住一个指针就足以定位所有局部变量的地址。为什么lambda表达式会构造这么大的未命名函数对象?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-18 08:12:11

我不明白你为什么看起来很惊讶。

C++标准提供了一组需求,每个实现都可以自由选择满足需求的任何策略。

为什么实现要优化lambda对象的大小?

具体而言,您是否意识到这将如何将此lambda生成的代码绑定到为周围函数生成的代码?

很容易说嘿!这是可以优化的!,但它更难实际优化,并确保它在所有边缘的情况下工作。因此,就我个人而言,我更喜欢简单和有效的实现,而不是对其进行优化的拙劣尝试。

..。尤其是当工作是这么容易的时候

代码语言:javascript
运行
复制
struct S { int a, b, c, d, e, f, g; };

int main() {
    S s = {};
    auto func = [&](){
        std::cout << s.a << s.b << s.c << s.d << s.e << s.f << s.g << "\n";
    };
    std::cout << sizeof(func) << "\n";
    return 0;
}

看,妈:只有4个字节!

票数 6
EN

Stack Overflow用户

发布于 2015-07-09 14:33:36

编译器通过堆栈指针引用捕获是合法的。有一个轻微的缺点(因为必须将偏移添加到所述堆栈指针中)。

在包含缺陷的当前C++标准下,还必须通过伪指针捕获引用变量,因为绑定的生存期必须与引用到数据的时间一样长,而不是它直接绑定到的引用。

更简单的实现(每个捕获的变量对应于构造函数参数和类成员变量)具有与“更正常”的C++代码一致的严重优势。需要为神奇的this做一些工作,但除此之外,lambda闭包是一个带有内联operator()的沼泽标准对象实例。关于“更正常”C++代码的优化策略将有效,bug将与“更正常”代码大部分相同,等等。

如果编译器编写器与堆栈框架实现一起使用,那么该实现中的引用捕获可能无法像在其他编译器中那样工作。当缺陷得到解决(有利于它的工作),代码将不得不再次更改。本质上,使用更简单实现的编译器几乎肯定会比那些使用高级实现的编译器拥有更少的bug和更多的工作代码。

有了堆栈帧捕获,对lambda的所有优化都必须为该lambda定制。它相当于一个类,它捕获一个void*,对其执行指针算法,并将结果数据转换为类型化指针。这将是非常难优化的,因为指针算法往往会阻塞优化,特别是堆栈变量之间的指针算法(通常是未定义的)。更糟糕的是,这种指针算法意味着堆栈变量状态(消除变量、重叠生存期、寄存器)的优化现在必须以纠缠方式与lambdas的优化交互。

进行这样的优化将是一件好事。另外,由于lambda类型与编译单元相关联,因此对lambda实现的混乱不会破坏编译单元之间的二进制兼容性。因此,一旦这些更改被证明是稳定的改进,您就可以相对安全地进行这些更改。但是,如果您确实实现了该优化,那么您真的希望能够恢复到经过验证的更简单的优化。

我鼓励您为您最喜欢的开源编译器提供补丁,以添加此功能。

票数 3
EN

Stack Overflow用户

发布于 2014-04-18 07:41:21

因为这就是它的实现方式。我不知道标准是否说明了它应该如何实现,但我猜它的实现定义了在这种情况下lambda对象的大小。

作为优化,编译器存储单个指针并使用偏移量来执行您建议的操作是没有什么问题的。也许有些编译器会这么做,我不知道。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23149555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档