什么是memcpy和C中的等号之间的效率差异?

时间:2015-09-02 06:24:01

标签: c memcpy

我经常使用memcpy来复制C / C ++中的结构。 我看到有人使用等号在C / C ++中直接复制struct。 例如:

struct A { char* name; int value; };
struct B { struct A happy[10]; }; 

struct A a1, a2;
struct B b1, b2;
memcpy(&a1, &a2, sizeof(struct A));
b1 = b2;

memcpy和等号之间的效率差异是什么?

3 个答案:

答案 0 :(得分:5)

现在已经删除了c ++标记,我们正在谈论C而不是C ++。

假设a1a2是同一struct类型的变量

memcpy(&a1, &a2, sizeof(struct A));

a1 = a2;

做同样的事情。

但如果分配运算符实际使用memcpy,则完全取决于编译器。

答案 1 :(得分:3)

C ++

在C ++中,结构可以是普通的旧数据(C类型)或复杂的 - 需要调用构造和复制构造函数。

memcpy和=之间的区别是=工作。

当=应用于复杂结构时,它会按照规则复制每个成员。 当=应用于一个简单的结构(普通旧数据或POD)时,它会执行" memcpy"。

C

在C复合体中,最初不允许复制,因此一些旧代码会使用=来记忆。在C中,它们等同于相同的操作。

答案 2 :(得分:2)

C!= C ++ ...让我们假设C情况,你不能重载赋值运算符。

值得查看测试用例的clang输出:

struct A { char* name; int value; };
struct B { struct A happy[10]; }; 

void foo() {
  struct A a1, a2;
  struct B b1, b2;
  memcpy(&a1, &a2, sizeof(struct A));
  b1 = b2;
}

运行以下命令使clang输出LLVM字节码:

clang -S -emit-llvm foo.c -o -

哪个输出

; Function Attrs: nounwind uwtable
define void @foo() #0 {
  %a1 = alloca %struct.A, align 8
  %a2 = alloca %struct.A, align 8
  %b1 = alloca %struct.B, align 8
  %b2 = alloca %struct.B, align 8
  %1 = bitcast %struct.A* %a1 to i8*
  %2 = bitcast %struct.A* %a2 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 16, i32 8, i1 false)
  %3 = bitcast %struct.B* %b1 to i8*
  %4 = bitcast %struct.B* %b2 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %4, i64 160, i32 8, i1 false)
  ret void
}

有趣的是,在两种情况下(呼叫memcpy或分配运营商)都会生成对@llvm.memcpy.p0i8.p0i8.i64的调用!