Ale*_*nov 5 c c++ gcc struct clang
例如给定
typedef struct A {
int a;
int b;
int c;
} A;
typedef struct B {
int d;
int e;
int f;
} B;
void f(B& b1, A& a2) {
b1.d = a2.a;
b1.e = a2.b;
b1.f = a2.c;
}
Run Code Online (Sandbox Code Playgroud)
f可以用 a 替换memcpy(特别是如果结构有更多字段)。
两个版本都会产生等效的代码吗?
如果我们复制到的结构的字段少于A?IE
typedef struct C {
int g;
int h;
} C;
void h(C& c1, A& a2) {
c1.g = a2.a;
c1.h = a2.b;
}
Run Code Online (Sandbox Code Playgroud)我很感兴趣,因为我正在生成包含这样的结构副本的代码,通常会更改字段的顺序,我想知道是否应该对这些情况进行特殊处理。
包含 C 标记是因为我希望 C 中的行为是相同的(模指针而不是引用)。
您的测试用例没有加载和存储足够的内存,因此值得转换为 memcpy。使用两倍的成员:
typedef struct A { int a, b, c, p, q, r; } A;
typedef struct B { int d, e, f, s, t, u; } B;
void f(B& b1, A& a2) {
b1.d = a2.a;
b1.e = a2.b;
b1.f = a2.c;
b1.s = a2.p;
b1.t = a2.q;
b1.u = a2.r;
}
Run Code Online (Sandbox Code Playgroud)
... LLVM 将代码优化为:
f(B&, A&): # @f(B&, A&)
movups (%rsi), %xmm0
movups %xmm0, (%rdi)
movl 16(%rsi), %eax
movl %eax, 16(%rdi)
movl 20(%rsi), %eax
movl %eax, 20(%rdi)
retq
Run Code Online (Sandbox Code Playgroud)
...使用未对齐的 16 字节加载/存储复制前四个成员。