c++ - 为什么用户编写的构造函数会影响生成的程序集?

标签 c++ compiler-construction compilation

测试环境:vs 2008, Debug模式

测试代码为:

// a demo for return value

class C
{
public:
    int value;
    int value2;
    int value3;

    //C(int v=0): value(v) {};
};

C getC(int v)
{
    C c1;

    return c1;
}



int main()
{
    C c1 = getC(10);

    return 0;
}

汇编输出是:

; 39   :    C c1 = getC(10);

push    10                  ; 0000000aH
lea eax, DWORD PTR $T2595[ebp]
push    eax
call    ?getC@@YA?AVC@@H@Z          ; getC
add esp, 8
mov ecx, DWORD PTR [eax]
mov DWORD PTR $T2594[ebp], ecx
mov edx, DWORD PTR [eax+4]
mov DWORD PTR $T2594[ebp+4], edx
mov eax, DWORD PTR [eax+8]
mov DWORD PTR $T2594[ebp+8], eax
mov ecx, DWORD PTR $T2594[ebp]
mov DWORD PTR _c1$[ebp], ecx
mov edx, DWORD PTR $T2594[ebp+4]
mov DWORD PTR _c1$[ebp+4], edx
mov eax, DWORD PTR $T2594[ebp+8]
mov DWORD PTR _c1$[ebp+8], eax

从 asm 输出中,我们可以看到编译创建了 2 个临时对象。

但是,当我如下定义构造函数时:

C(int v=0): value(v) {};

重新编译程序,asm输出变成:

; 39   :    C c1 = getC(10);

push    10                  ; 0000000aH
lea eax, DWORD PTR _c1$[ebp]
push    eax
call    ?getC@@YA?AVC@@H@Z          ; getC
add esp, 8

显然,编译器优化了代码,我的问题是:

为什么添加用户编写的构造函数对生成的程序集影响如此之大?

最佳答案

这个问题是关于 C++ 中的复制省略和返回值优化。

我建议你不要花太多时间在上面,因为生成的汇编代码取决于编译器。

复制省略在标准中定义:

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy/move operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization. This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):

[...]

§12.8 [class.copy]

stackoverflow 上已经有一个问题可以引用,see here .

关于c++ - 为什么用户编写的构造函数会影响生成的程序集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12881210/

相关文章:

c++ - 选择一组具有最高值总和的区间的算法

java - 用于测试和主要的不同 Maven 编译器版本

c - 显式算术,编译器会处理它吗?

c - 关于添加错误标志的问题

c++ - 无法使用 Xcode 6.0.1 编译 Qt

c++ - 为什么在这种情况下指针变慢

使用 vector 初始化链表时出现c++段错误

c++ - 指向 const 的指针与通常的指针(对于函数)

c++ - 是否可以手动计算类成员的字节偏移量?

compiler-construction - Web Essentials Less 上的导入文件保存不编译主文件