gpt4 book ai didi

c++ - 为什么我手写的复制构造函数生成的代码与默认代码不同?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:47:09 26 4
gpt4 key购买 nike

我正试图为我刚才遇到的一个问题 ( Automatically determine if user-defined function is equivalent to the implicit one ) 找到答案。我的想法是,我将编译进出复制构造函数,然后反汇编代码,并检查它们是否相同。代码:

struct A
{
int B;
A() : B(0) { }
#ifdef COPY_CONSTRUCTOR
A(const A& a) : B(a.B) { }
#endif
};

#include <stdio.h>
int main()
{
A a;
A b(a);
printf("%d", b.B);
}

编译(cygwin gcc v4.9.3):

gcc -o a1.exe main.cpp -std=c++11 -g -O0 -DCOPY_CONSTRUCTOR
gcc -o a2.exe main.cpp -std=c++11 -g -O0 -fno-elide-constructors

然后将反汇编转储到复制构造函数(_ZN1AC1ERKS_ 是 A 的复制构造函数的错位名称):

gdb -batch -ex 'file a1.exe' -ex 'disass _ZN1AC1ERKS_'

产生:

Dump of assembler code for function A::A(A const&):
0x0000000100401770 <+0>: push %rbp
0x0000000100401771 <+1>: mov %rsp,%rbp
0x0000000100401774 <+4>: mov %rcx,0x10(%rbp)
0x0000000100401778 <+8>: mov %rdx,0x18(%rbp)
0x000000010040177c <+12>: mov 0x18(%rbp),%rax
0x0000000100401780 <+16>: mov (%rax),%edx
0x0000000100401782 <+18>: mov 0x10(%rbp),%rax
0x0000000100401786 <+22>: mov %edx,(%rax)
0x0000000100401788 <+24>: pop %rbp
0x0000000100401789 <+25>: retq
End of assembler dump.

和:

gdb -batch -ex 'file a2.exe' -ex 'disass _ZN1AC1ERKS_'

产生:

Dump of assembler code for function A::A(A const&):
0x0000000100401770 <+0>: push %rbp
0x0000000100401771 <+1>: mov %rsp,%rbp
0x0000000100401774 <+4>: mov %rcx,0x10(%rbp)
0x0000000100401778 <+8>: mov %rdx,0x18(%rbp)
0x000000010040177c <+12>: mov 0x10(%rbp),%rax
0x0000000100401780 <+16>: mov 0x18(%rbp),%rdx
0x0000000100401784 <+20>: mov (%rdx),%edx
0x0000000100401786 <+22>: mov %edx,(%rax)
0x0000000100401788 <+24>: pop %rbp
0x0000000100401789 <+25>: retq
End of assembler dump.

除了 mov 0x10(%rbp),%rax 这行以不同的顺序出现之外,它们是相同的。在这种情况下,它是无害的,但显然会使等价检测更加困难。差异的解释是什么?

最佳答案

你的问题让我很好奇,所以我必须亲自看看。你可以查看here for version 1here for version 2看看结果实际上是相同的。

两个变体都被优化掉了!

这是反汇编:

.LC0:
.string "%d"
Test():
push 0
push OFFSET FLAT:.LC0
call printf
pop eax
pop edx
push 0
push OFFSET FLAT:.LC0
call printf
pop ecx
pop eax
ret

要了解未优化版本为何不同,您可能需要检查 gcc 的来源。

Visual Studio 也给出相同的结果:

int main()
{
A a;
A b(a);
printf("%d", b.B);
00B41000 push 0
00B41002 push 0B499A0h
00B41007 call printf (0B4102Dh)
printf("%d", a.B);
00B4100C push 0
00B4100E push 0B499A4h
00B41013 call printf (0B4102Dh)
00B41018 add esp,10h
return 0;
0127101B xor eax,eax
}
0127101D ret

关于c++ - 为什么我手写的复制构造函数生成的代码与默认代码不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42632555/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com