绝对没有必要避免或更换memcpy()
如果您正在努力优化,请致电。每个现代优化编译器都不会发出调用并生成等效的汇编代码。较新的 GCC 和 Clang 版本甚至在没有给出优化相关选项的情况下也会这样做。可以通过以下方式禁用该行为-fno-builtin
顺便一提。
您可以使用以下方法自行验证C++ 编译器资源管理器 http://gcc.godbolt.org/#%7B%22version%22%3A3%2C%22filterAsm%22%3A%7B%22labels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue%2C%22colouriseAsm%22%3Atrue%7D%2C%22compilers%22%3A%5B%7B%22sourcez%22%3A%22MQSwdgxgNgrgJgUwAQB4DOAXATuA5gOgAsA%2BAKFElkVUznAyLNJnoDYAWAfQ2YA4MA9jA4AKFmAy9uSCALCYkMXgG1MAQwwgISXgF0AlKQDepJIrZcMijgG5TSALYIHEAA4BPEQDJh7ADSKvAFoIABeCAIAZtbs%2BnZmWAgYMFhgMXYAvqRAAAA%3D%3D%22%2C%22compiler%22%3A%22g492%22%2C%22options%22%3A%22-x%20c%20-std%3Dc99%20-Wall%20-Wextra%20-Wpedantic%22%7D%5D%7D(或本地与-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
这篇博文 http://blog.regehr.org/archives/959John Regehr 得出了同样的结论(c5()
calls memcpy()
):
在我看来c5
是这个小代码中最容易理解的
一批功能,因为它不会进行混乱的移位,而且
它完全、完全、显然没有可能出现的并发症
源于令人困惑的联合规则和严格的别名。它
几年前,当我
发现编译器可以看穿memcpy
并生成
正确的代码。
使用联合或按位运算等替代方案可能不会产生最佳(并且看起来不错)代码,或者不能在 ISO C90 或 C++ 中使用(这也包括 GCC 的__may_alias__
评论部分提到的属性)。