How to efficiently copy small data from char buffer without violating strict alias rules?

The answer is in another question: A strict anti-aliasing rule and char * pointers say that using char* to check the binary contents of an T object is ok. But using T* for overlay in char buffer is not suitable.

Now I have a function that takes a char buffer with binary data. And does such things by reading this:

 // unsigned char *pData used to walk through the buffer. uint32_t value = *(unit32_t*)pData; pData += 4; 

If I break a strict alias by doing this, what other, more efficient ways are available? Will compilers be able to optimize memcpy calls when called with few bytes?

+4
source share
2 answers

If I break a strict alias by doing this ...

Yes you do

What other, more effective ways are available?

If the buffer must be char , before you access the value, you need to use memcpy in uint32_t . Of course, if all your values ​​were uint32_t s, you could create a uint32_t s buffer and pass it to a function that fills it with char s, since strict anti-aliasing is a one-way ban, i.e. using a uint32_t* like char* .

Will compilers optimize memcpy calls when called with few bytes?

Many CPUs have built-in instructions for memcpy . Modern compilers use these instructions for good performance.

+2
source

Will compilers optimize memcpy calls when called with few 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 team 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, modern compilers won't even call a procedure.

+1
source

All Articles