c++ - GCC 和 Clang 是否优化逐字段结构复制?

标签 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;
}

f 可以替换为 memcpy(特别是如果结构有更多字段)。

  1. 两个版本会产生相同的代码吗?

  2. 如果我们复制到的结构的字段少于 A 怎么办?即

    typedef struct C {
        int g;
        int h;
    } C;
    
    void h(C& c1, A& a2) {
        c1.g = a2.a;
        c1.h = a2.b;
    }
    

我很感兴趣,因为我生成的代码包括这样的结构拷贝,通常会更改字段的顺序,我想知道是否应该对这些情况进行特殊处理。

包含 C 标记是因为我希望 C 中的行为是相同的(取模指针而不是引用)。

最佳答案

根据 godbolt.org,带有 -O2 的 x86-64 gcc 6.2 产生

mov eax, DWORD PTR [rsi]
mov DWORD PTR [rdi], eax
mov eax, DWORD PTR [rsi+4]
mov DWORD PTR [rdi+4], eax
mov eax, DWORD PTR [rsi+8]
mov DWORD PTR [rdi+8], eax

对于逐个字段的复制,

mov rax, QWORD PTR [rsi]
mov QWORD PTR [rdi], rax
mov eax, DWORD PTR [rsi+8]
mov DWORD PTR [rdi+8], eax

用于 memcpy。 clang 和 icc 都有相似的区别。有点失望。

关于c++ - GCC 和 Clang 是否优化逐字段结构复制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41061378/

相关文章:

c++ - 碰撞检测和时间复杂度 : How do I make checking for collisions easier?

c - %s 和 %1024s 之间的差异

c - 使用 malloc 创建二维和一维数组时出错

c - `va_num` 在这个可变参数宏中意味着什么?

c++ - CGREEN编译错误: ‘assertion_tests’ does not name a type

c++ - 使用 union 作为 boost::asio 的序列化器

c++ - 在 C++ 中使用 RWCString 读取文本文件时获取 RWBoundsErr

c - 什么 child 不从其 parent 那里继承信号量调整(semop(2))是什么意思?

gcc - 我如何使用 objdump 之类的东西判断目标文件是否是使用 -fPIC 构建的?

c - 需要在 C 中包含库吗?