Reputation: 19451
The answer in the another question: Strict aliasing rule and 'char *' pointers says that using a char*
to examine the binary contents of a T
object is ok. But using a T*
to overlay on a char buffer is not ok.
Now I have a function that takes a char buffer with binary data. And does things like this while reading it:
// unsigned char *pData used to walk through the buffer.
uint32_t value = *(unit32_t*)pData;
pData += 4;
If I break the strict aliasing by doing this, what other, more effective ways available? Will compilers optimize memcpy calls when they are called with small amount of bytes?
Upvotes: 5
Views: 355
Reputation:
Will compilers optimize memcpy calls when they are called with small amount of bytes?
For this sample code:
#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 generated this assembly output (release build, 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
So yes, modern compilers won't even call the procedure.
Upvotes: 2
Reputation: 726967
If I break the strict aliasing by doing this ...
Yes, you do
what other, more effective ways available?
If the buffer must be char
, you need to use memcpy
into uint32_t
before accessing the value. Of course if all your values were uint32_t
s, you could make a buffer of uint32_t
s, and pass it to the function that fills it with char
s, because strict aliasing is a one-way prohibition, i.e. using a uint32_t*
as a char*
is allowed.
Will compilers optimize memcpy calls when they are called with small amount of bytes?
Many CPUs have built-in instructions for memcpy
. Modern compilers use these instructions for good efficiency.
Upvotes: 3