我目前的做法(我更愿意摆脱memcpy
电话):
uint64_t integer;
uint8_t string[8];
...
memcpy(&integer, &string, 8); //or swap the parameters
假设integer
数组长度始终为8的倍数(总分配为64位)是否可以在给定编译器填充/对齐问题的情况下进行直接转换?
答案 0 :(得分:4)
如果您正在努力优化,则无需避免或替换memcpy()
来电。每个现代优化编译器都不会发出调用并生成等效的汇编代码。较新的GCC和Clang版本甚至在没有给出优化相关选项时也会这样做。顺便说一句,可以使用-fno-builtin
禁用该行为。
您可以使用C++ Compiler Explorer(当然还有本地-S
)自行验证:
#include <string.h>
#include <stdint.h>
uint64_t
u8tou64(uint8_t const u8[static 8]){
uint64_t u64;
memcpy(&u64, u8, sizeof u64);
return u64;
}
例如,针对x86_64的GCC 4.8.1产生:
u8tou64:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-24], rdi
mov rax, QWORD PTR [rbp-24]
mov rax, QWORD PTR [rax]
mov QWORD PTR [rbp-8], rax
mov rax, QWORD PTR [rbp-8]
pop rbp
ret
使用-O3
:
u8tou64:
mov rax, QWORD PTR [rdi]
ret
John Regehr的 This blog post得出了相同的结论(c5()
调用memcpy()
):
在我看来,
c5
是最容易理解的代码 一批功能,因为它不会做凌乱的转移也 它完全,完全,显然没有可能的并发症 来自工会的混乱规则和严格的混淆。它 几年前当我成为打字的时候,我成了我的首选成语 发现编译器可以透过memcpy
看到并生成 正确的代码。
使用联合或按位运算等替代方法可能不会产生最佳(且看起来不错的)代码,或者无法在ISO C90或C ++中使用(这也包括GCC&#39; __may_alias__
属性这在评论部分提到。)