A destructive guard pointer type will violate strict aliasing rules [-Wstrict-aliasing]

I am really confused.

uint8_t hash[20];
uint32_t u;

// Setting hash to some value here...

u = *(uint32_t*) hash;

      

This *(uint32_t*) hash

raises a warning:

Dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

...

I think there is something wrong with typecasting, but I'm not sure because I don't know how *(type*) var

the typecasting method works. It seems to be pointing to an object with an asterisk inside too. I'm confused that the thing that makes me ask a question about this. I would especially like to know how type*

different from *(type*)

. It can help you get rid of this warning. Thanks in advance.

+3


source to share


1 answer


You are not allowed to interpret an object through an incompatible pointer like you:

*(uint32_t*) hash;

      

This will lead to alignment, content issues, and strict aliases breaking, leading to undefined behavior.

What happens is you are interpreting the first four bytes of the hash of the array as an unsigned 32 bit integer.



 uint32_t* p = ( uint32_t* )hash ;  //cast must be there, pointer p is not valid 
 uint32_t u = *p ;  //dereference the pointer, this is undefined behaviour

      

If your byte array encodes a small trailing 32-bit unsigned integer, this is a portable, independent way of byte ordering:

#include <stdint.h>
#include <limits.h>

uint8_t h[] = { 3 , 2 , 1 , 0 } ;  //1*3 + 256*2 + 65536*1 + 16777216 * 0
uint32_t a = 0 ;

for( size_t i = 0 ; i < sizeof( a ) ; i++ )
{
    a = a | (  h[i] << ( CHAR_BIT*i ) ) ;
}

printf("%u" , a ) ;  //66051

      

+1


source







All Articles