取消引用类型冲突指针将破坏严格别名规则[-Wstrict-aliasing] [英] Dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

查看:5841
本文介绍了取消引用类型冲突指针将破坏严格别名规则[-Wstrict-aliasing]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很困惑。

  uint8_t hash [20]; 
uint32_t u;

//在这里将哈希设置为某个值...

u = *(uint32_t *)hash;

*(uint32_t *)hash 警告:



取消引用类型冲突指针将破坏严格别名规则[-Wstrict-别名]



我认为这是错误的typecasting,但我不知道,因为我不清楚如何 *(type *) var 类型转换的方法实际上工作。它似乎指向一个内部有一个星号的对象。我很困惑,这是迫使我提出一个问题的事情。
特别是我想知道 type < *(type *)有何区别。这可能是很多帮助摆脱这个警告。
提前感谢。

解决方案

不允许你通过一个不兼容的指针来解释对象: / p>

  *(uint32_t *)hash; 

这样做会导致对齐,字节顺序和违反严重别名的问题,导致未定义的行为。 p>

会发生什么,将数组哈希的前四个字节解释为无符号的32位整数。

  uint32_t * p =(uint32_t *)hash; // cast必须存在,指针p无效
uint32_t u = * p; //解引用指针,这是未定义的行为

如果你的字节数组是小尾数法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 {
a = a | (h [i] <(CHAR_BIT * i));
}

printf(%u,a); // 66051


I'm really confused.

uint8_t hash[20];
uint32_t u;

// Setting hash to some value here...

u = *(uint32_t*) hash;

This *(uint32_t*) hash causes a warning:

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

I think it's something wrong in typecasting, but I'm not sure, because I don't clearly know on how *(type*) var way of typecasting actually works. It seem to point on an object with an asterisk inside too. I am confused, that's the thing which forces me to ask a question about that. Especially I'd like to know how type* differs from *(type*). This may be a lot of help to get rid of this warning. Thanks in advance.

解决方案

You are not allowed to interpret an object trough an incompatible pointer as you do:

*(uint32_t*) hash;

Doing that will cause problems with alignment, endianness and violating strict aliasing which will cause undefined behaviour.

What happens is, you interpret the first four bytes of the array hash 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 is encoding little endian 32 bit unsigned integer, this is the portable, byte-order independent way of extracting:

#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

这篇关于取消引用类型冲突指针将破坏严格别名规则[-Wstrict-aliasing]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆