我真的很困惑。
uint8_t hash[20];
uint32_t u;
// Setting hash to some value here...
u = *(uint32_t*) hash;
此*(uint32_t*) hash
会发出警告:
Dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
。
我认为在类型转换中出现了问题,但我不确定,因为我并不清楚*(type*) var
类型转换的实际工作方式。它似乎指向一个内有星号的物体。我很困惑,这是迫使我提出问题的事情。
特别是我想知道type*
与*(type*)
的区别。这可能是摆脱这个警告的很多帮助。
提前谢谢。
答案 0 :(得分:1)
您不能像以下那样通过不兼容的指针解释对象:
*(uint32_t*) hash;
这样做会导致对齐,字节序和违反严格别名的问题,这会导致未定义的行为。
当您将数组哈希的前四个字节解释为无符号32位整数时,会发生什么。
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
如果你的字节数组是编码小端32位无符号整数,那么这是一种可移植的,无字节顺序的提取方式:
#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