This question already has answers here:
What is the strict aliasing rule?

(11个答案)


6年前关闭。




我真的很困惑
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*)有何不同。摆脱此警告可能对您有很大帮助。
提前致谢。

最佳答案

不允许通过不兼容的指针解释对象,就像这样做:

*(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

关于c++ - 取消引用类型化指针会破坏严格混叠规则[-Wstrict-aliasing] [duplicate],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26713851/

10-09 13:37