Casting and then dereferencing pointers in C

When working with char buffers in C, it is sometimes useful and more efficient to work with int sized chunks of data at a time. To do this, I can apply char * to int * and use this pointer. However, I'm not entirely sure that this works the way I think.

For example, suppose I have char *data , and *(int32_t *)data = -1 always overwrite bytes data[0] , data[1] , data[2] and data[3] and no other bytes?

+4
source share
3 answers

Extension of my comment.

There are two main problems here:


Violation of strict anti-aliasing is technically undefined behavior . You are allowed an alias of any data type with char* , but not vice versa.

You can get around the issue with f[no-]strict-aliasing in GCC.


Another problem is alignment. The char pointer may not be aligned correctly. Access to inconsistent data can lead to performance degradation or even hardware failure if the hardware does not support inconsistent access.


If performance is not an issue, the full way is memcpy() in the buffer of the int array.

After fixing these two issues, your example:

 *(int32_t *)data = -1 

rewriting data[0] , data[1] , data[2] and data[3] should work as expected if sizeof(int32_t) == 4 . Just pay attention to reliability ...

+5
source

This is technically undefined behavior, and the standard does not talk about the results of alias pointers like this. A standard pedant would say that invoking undefined behavior in this way can lead to anything from corrupted data to a system crash in Ragnarok.

Pragmatically, it depends on your equipment. Most modern systems (for example, x86, x64, PPC, MIPS, ARM) process word size records in the form in which you describe, except that writing to a non-primary address will lead to failure. Moreover, this is when the principle of fate comes into force; on a small system

 char foo[4]; *((uint_32*)(foo)) = 0x01020304; // the following are now true: foo[0] == 0x04; foo[1] == 0x03; foo[2] == 0x02; foo[3] == 0x01; 

The short answer is that it’s not safe if you don’t know exactly what hardware your program will run on.

If you control the hardware for which you are compiling, you can predict what the compiler will do; I used this trick to speed up the packing of byte arrays on embedded systems.

+3
source

No, not necessarily. If the data is not aligned correctly, it may not work. Assuming it is correctly aligned, it will probably overwrite the following sizeof(int) bytes and nothing else, but I'm not sure that even this is fully guaranteed.

+1
source

Source: https://habr.com/ru/post/1393701/


All Articles