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

调用函数时MSVC未省略拷贝,是否符合C++标准?

MSVC临时对象拷贝行为是否符合C++标准?

以下是测试代码:

#include <cstdio>

struct Foo {
    ~Foo() {
        printf("~Foo\n");
    }
};

void foo(Foo) {
}

int main() {
    foo(Foo());
}

按照C++标准的**复制消除(Copy Elision)**规则,这段代码中main调用foo(Foo())时,编译器应当直接将临时对象Foo()作为foo的形参初始化,仅创建一个Foo实例,对应一次~Foo输出。

但实际测试中:

  • 使用MSVC编译时,输出两行~Foo,说明创建了两个Foo对象(推测一个是main中的临时对象,另一个是foo的形参);
  • 使用GCC编译时仅输出一行~Foo,符合预期;
  • 若为Foo添加空拷贝构造函数,MSVC也只会输出一行~Foo。

结论

这种情况不符合C++标准。

根据C++11及以后的标准规定,当临时对象被用来直接初始化同一类型的对象时(比如用临时对象作为函数实参初始化按值传递的形参),编译器必须执行复制消除,不允许生成额外的拷贝或移动操作,因此只能存在一个Foo实例。

MSVC在未显式定义拷贝构造函数时的行为违反了这一强制规则——它没有正确应用复制消除,反而生成了额外的拷贝。而当添加用户定义的拷贝构造函数后,MSVC才触发了合规的复制消除,这说明其默认行为存在标准合规性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:22:36