另一个问题的答案:Strict aliasing rule and 'char *' pointers表示使用Activity
检查char*
对象的二进制内容是可以的。但是使用T
覆盖char缓冲区是不行的。
现在我有一个带有二进制数据的char缓冲区的函数。在阅读时会做这样的事情:
T*
如果我通过这样做打破严格的混叠,还有哪些更有效的方法?编译器在用少量字节调用时是否会优化memcpy调用?
答案 0 :(得分:2)
如果我通过这样做打破严格的别名......
是的,你做了
还有哪些更有效的方法?
如果缓冲区必须为char
,则需要在memcpy
之前使用uint32_t
才能访问该值。当然,如果你的所有值都是uint32_t
s,你可以创建uint32_t
s的缓冲区,并将其传递给用char
s填充它的函数,因为严格别名是一个允许使用uint32_t*
作为char*
。
编译器在用少量字节调用时是否会优化memcpy调用?
许多CPU都有memcpy
的内置指令。现代编译器使用这些指令以提高效率。
答案 1 :(得分:1)
编译器在用少量字节调用时是否会优化memcpy调用?
对于此示例代码:
#define _CRT_SECURE_NO_WARNINGS // To allow usage of scanf in vc++2015
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
// printf and scanf to prevent code elimination
char bytes[ 4 ];
scanf( "%s", bytes );
char buffer[ 4 ];
memcpy( buffer, bytes, 4 );
printf( "%s", buffer );
return 0;
}
Visual C ++ 2015生成了此程序集输出(发布版本,x64):
; memcpy was replaced by a simple register move
mov eax, DWORD PTR bytes$[rsp]
lea rdx, QWORD PTR buffer$[rsp] ; setting arguments
lea rcx, OFFSET FLAT:??_C@_02DKCKIIND@?$CFs?$AA@ ; for printf call
; at this point copied array was actually stored in memory
mov DWORD PTR buffer$[rsp], eax
call printf
所以,是的,现代编译器甚至不会调用该程序。