编译器能否合并定义相同的constexpr lambda?标准是否允许该优化?
关于C++ constexpr lambda是否可合并的疑问
我好奇编译器是否能对以下代码进行优化:
constexpr auto lambda = [](){return 5;}; constexpr auto lambda_same_definition = [](){return 5;};
让生成的functor仅保留一个。我知道lambda表达式的底层实现会为每个表达式创建匿名functor,但这里两个表达式完全相同且为constexpr,编译器似乎完全可以将它们合并为一个。当然我也清楚这种逻辑在通用场景下很难实现——判断两个函数是否等价大概率是不可判定问题。
但测试结果显示,编译器生成了两个不同类型名(NL6lambdaMUlvE_E1和NL22lambda_same_definitionMUlvE_E)的functor。因此我的问题是:这属于实现质量问题,还是C++标准禁止了该优化?
解答
这既不是实现质量问题,也不是标准禁止优化——C++标准要求每个lambda表达式对应唯一的闭包类型,所以编译器必须为这两个lambda生成不同的类型,自然无法合并它们的functor实例。
具体依据
- 按照C++标准规定,每个lambda表达式都会引入一个独特的、未命名的非联合类类型(即闭包类型)。哪怕两个lambda的代码定义完全一致,它们的闭包类型也属于不同类型。
- 这条规则对
constexprlambda同样生效,标准并没有因为lambda是编译期常量就放宽闭包类型唯一性的要求。 - 你看到的不同类型名,正是编译器严格遵循标准的结果——每个lambda必须拥有独立的闭包类型,所以编译器会生成不同的类型标识来区分它们。
补充说明
虽然标准不允许合并闭包类型,但在代码实际调用这两个lambda的场景中,编译器可以在优化阶段直接把调用替换为常量5(因为是constexpr),最终生成的机器码可能不会存在两个独立的函数体。不过这和合并闭包类型属于完全不同的优化方向。
内容的提问来源于stack exchange,提问作者k huang
相关产品推荐
相关产品推荐

