You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

常量求值期间是否允许Copy elision(如NRVO)?MSVC行为合规性探讨

常量表达式中复制消除的编译器行为疑问

在常量表达式和常量初始化中,从不执行复制消除。

但实际测试中存在例外情况:以下代码定义了constexpr函数f,它返回A类型对象res,同时接收同类型对象指针p作为参数。只有在**命名返回值优化(NRVO)**生效的场景(比如A res = f( &res )这类写法)下,才会出现&res == p为真的情况:

struct A {
    bool nrvo = false;
};

constexpr A f( A * p = nullptr ) {
    A res = p ? A{ .nrvo = &res == p } : f( &res );
    return res;
}

// 在MSVC中失败
static_assert( !f().nrvo );

按照标准预期,常量求值期间nrvo应该为false,但Visual Studio编译器会让这个断言失败。

这是MSVC的编译器实现错误。

根据C++标准,常量表达式求值过程中严格禁止复制消除(包括NRVO)——复制消除属于优化行为,而常量求值必须严格遵循标准语义,不能通过优化改变程序的可观测行为。MSVC错误地在常量求值流程中应用了NRVO,导致&res == p成立,违反了标准规定。

内容的提问来源于stack exchange,提问作者Fedor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 05:40:57