C / C ++如何复制结构?

时间:2013-02-15 11:25:14

标签: c++ c struct copy

按值在C / C ++中传递结构时,必须复制结构内容。编译器如何实现这一目标?即,通常为此副本发出哪些汇编指令?

这些时间有多快,例如与调用memcpy相比?

现在考虑以下代码:

struct X { int i, j, k; };

void foo(X x);

void foo( int i, int j, int k);

调用foo(X)和foo(int,int,int)之间有什么区别,或者生成的汇编代码是否相同(考虑参数的传递)?

4 个答案:

答案 0 :(得分:5)

在C ++中

  

编译器如何实现这一目标?

他们为该类/结构调用复制构造函数。如果您不提供一个或您提供的那个,则隐式生成一个。

  

这些时间有多快,例如:与拨打memcpy

相比

取决于班级及其成员。分析应该给你一个更清晰的图像 但是,应避免使用memcpy复制类实例。

在C

  

编译器如何实现这一目标?

他们为该结构执行 shallow copy 。出于所有实际目的,您可以将其视为与memcpy相同。

答案 1 :(得分:4)

显然,如果有structclass的构造函数,则调用构造函数。

如果没有构造函数,则完全取决于编译器,但很可能,对于三个整数大小的对象,它可能是三个单独的mov指令。对于较大的结构,可以是对memcpy的调用,也可以是与memcpy类似的内联版本。

如果结构非常大(几兆字节),那么很可能真正的memcpy比内联版本快,并且编译器可能没有意识到这一点并且无论如何都使用内联版本。但是我们大多数人都没有使用兆字节的大型结构,所以我不认为通常会有太多担心。如果结构大兆字节,则将结构作为参数复制到堆栈上,考虑到典型堆栈的受限大小,首先可能不是一个好主意。

答案 2 :(得分:3)

有两个令人不安的案例。

  • 如果你的结构是 POD ,那么副本会得到优化,并且会像memcpy一样快(具有适当的优化级别)。

  • 如果您的结构不是POD ,C ++必须为您的对象调用复制构造函数。复制构造函数可以调用其他函数,新运算符等,因此它将比memcpy慢。但是memcpy不会正确复制结构,在非POD类型上使用memcpy会导致未定义的行为!

请注意,例如在g++中,对memcpy的调用将被内联并优化。由于struct copy和memcpy调用之间的意图完全相同(从位置Y到Z复制X个字节),我认为生成的汇编代码不会有所不同。

无论如何,确定,通过分析代码的汇编来找出它。


编辑:只需阅读有关函数参数的问题的结尾。请注意,函数参数传递通常(特别是在x64中)在寄存器中完成,并且比memcpy快得多。

我检查了汇编代码,他们做差异。确切的代码取决于您当前编译器使用的calling convention。对我来说,struct不会在寄存器中传递,而是在堆栈上传递并生成实际的副本。这三个int%ecx%edx%r8d中传递。我在Windows GCC上试过这个。它似乎使用Windows x64呼叫对话。

有关如何传递参数的更多信息,请查看调用约定的规范。所有的细节和角落案例都得到了解决。例如。对于x64 GCC,请查看System V AMD64 ABI第3.2.3章参数传递。对于Visual Studio,请查看here

答案 3 :(得分:0)

Alok Save查看的另一个答案。在中,它可以是memcpy(或等效的)或内联版本(对于具有良好大小的结构,最多可以有mov个实例)。

相关问题