warning: dereferencing type-punned pointer will break strict-aliasing rules

【转载自】http://www.zeali.net/entry/454

【以下是原文】

warning: dereferencing type-punned pointer will break strict-aliasing rules

  在 gcc 2.x 下编译没有任何 warning 信息的代码换到 gcc 3.x 版本下之后出现了类似的 warning 。原因是 gcc 3 引入了 strict aliasing 架构,当编译时使用了-fstrict-aliasing 参数(该参数在使用了-O2 , -O3, -Os 优化参数的情况下默认生效),而源代码中存在一些违反了 strict-aliasing 规则的地方的话,编译器就会对这部分代码提出 warning 。

  gcc 3 manual 对于 -fstrict-aliasing 参数的说明是:Allows the compiler to assume the strictest aliasing rules applicable to the language being compiled.  For C (and C++), this activates optimizations based on the type of expressions.  In particular, an object of one type is assumed never to reside at the same address as an object of a different type, unless the types are almost the same.  For example, an "unsigned int" can alias an "int", but not a "void*" or a "double".  A character type may alias any other type.

  简而言之, 在该参数激活的情况下,编译器希望不同类型的对象不会指向同一个地址。比如像这段代码:

int retLen;
someSetFunc((unsigned long*)&retLen);
printf("ret len = %d\n",retLen);

  由于 someSetFunc 的传入参数类型定义为 unsigned long ,所以需要进行这样的指针类型强制 cast 。但对于 -fstrict-aliasing 优化参数来说,这样的转换是有潜在问题的(但实际上可能并不会造成任何问题)。所以如果现有的源代码存在太多这样的类型强制转换的问题的话,对这些代码进行修改也许会是场噩梦。最简单的方法是使用-fno-strict-aliasing 参数来关闭 gcc 的优化选项,代价是放弃了strict-aliasing 编译优化可能带来的可执行代码的性能提升。当然也可以用-Wno-strict-aliasing 来屏蔽相关的 warning 信息,但无论这些 warning 信息多么的无关紧要,总还是“疑似危险”,所以可能的话最好还是把所有的 warning 都消灭掉。

  消灭的方法也不算复杂,正如 gcc manual 所示的那样,可以是采用 union 的不同成员变量来完成类型的转换。上面那段代码可以改为:

union u_retLen
{
int retLen;
unsigned long ptr;
};
someSetFunc(&u_retLen.ptr);
printf("ret len = %d\n",u_retLen.retLen);

  虽然会使源代码变得丑陋,但对于大部分已有的源代码来说,这可能是改动最小的方案了。而对于新写的代码来说,如何更好的设计函数的入口参数(比如使用 void*)可能才是需要去思考的问题了。

【以上是原文】

 

先将某地址强制转换为void*型,再强制转换为其他类型,即可消除这个警告。可能是因为编译器对void*的强转不会有任何优化吧。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: dereferencing type-punned pointer是指对一个类型转换后的指针进行解引用操作。这种操作可能会导致未定义的行为,因为不同类型的指针可能具有不同的内存布局和对齐方式,解引用操作可能会访问到错误的内存位置,导致程序崩溃或产生不可预测的结果。因此,应该避免使用这种类型的指针操作。 ### 回答2: dereferencing type-punned pointer(解引用类型转换指针) 首先需要了解的是类型转换指针,它是一个指针,它可以将一个变量解释为不同类型的变量。例如,一个int型指针可以转换为一个char型指针,它可以让程序员通过不同类型查看同一块内存区域,但是这个过程是非常危险的,尤其是在解引用指针时,很容易引发问题。 当我们使用一个指针解引用时,我们希望得到的是一个合法的内存地址,即指向有效的对象的指针。但是如果我们使用一个类型转换指针,则不一定能够保证指针指向的内存区域是有效的。这种情况可能导致非法的内存访问、程序崩溃,并可能导致安全漏洞。例如,以下代码使用了一个类型转换指针: ``` int a = 10; float b = *(float*)&a; ``` 这个代码段将一个整数a的地址解释为一个浮点数b的地址,并通过解引用类型转换指针来获取浮点数的值。如果a的内存区域不足以容纳一个浮点数,或者已经被释放了,那么这个代码就会引起问题。 解决这个问题的方法是使用正确的类型来解引用指针,或者使用内存操作函数来完成转换。例如,在上面的例子中,我们可以使用以下代码来完成类型转换: ``` int a = 10; float b; memcpy(&b, &a, sizeof(float)); ``` 这个代码使用了memcpy函数将一个整数a的地址复制到一个float类型的变量b中。这种方法可以保证我们不会出现类型转换指针导致的问题。 ### 回答3: dereferencing type-punned poin是指对通过类型转换得到指针的解引用操作。在C/C++中,类型转换是一种常见的操作,有时候我们需要将一个指针“重新解释”为另外一个指针类型,通过这种方式访问不同类型的数据。但是,这种做法实际上是非法的,可能会引起严重的后果。 具体来说,dereferencing type-punned poin可能会导致以下几个问题: 1.非法内存访问。由于类型转换后,指针所指向的数据类型发生了变化,新的数据类型可能会导致访问非法内存。 2.未定义的行为。C/C++标准中有很多规则限制了指针类型转换的行为,如果不遵守这些规则,可能会导致未定义的行为。 3.平台依赖性。某些类型转换可能会涉及平台依赖性,例如对指针进行位操作,这种做法可能会依赖于底层硬件的字节序等因素。 因此,避免dereferencing type-punned poin非常重要。如果确实需要进行类型转换,建议使用标准库中提供的转换函数,而不是手动进行位操作等操作。另外,在使用指针类型转换时,也要充分了解C/C++标准中的规则,以避免不必要的安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值