This question already has answers here:
What is the strict aliasing rule?
(11个答案)
6年前关闭。
我真的很困惑
此
我认为类型转换是错误的,但是我不确定,因为我不清楚类型转换的
特别是我想知道
提前致谢。
这样做会导致对齐,字节顺序出现问题,并违反严格的别名,这将导致不确定的行为。
发生的情况是,您将数组哈希的前四个字节解释为无符号的32位整数。
如果您的字节数组编码的是小端32位无符号整数,则这是可移植的,字节顺序无关的提取方式:
(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