指针别名警告实例
问题分析
- 原因由于强制类型转换导致出现的warning
- GCC 4 编译警告:warning: dereferencing type-punned pointer will break strict-aliasing rules
- 有一个指针用作了不同的类型,编译器告诉你如果坚持这样做,它不能做编译优化
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
int main() {
void *p = nullptr;
float f = 0.01;
*(float *)(&p) = f; //warning pointer aliasing
std::cout << "p = " << p << std::endl;
float f2 = *(float *)(&p);
std::cout << "f2 = " << f2 << std::endl;
}
- 知乎讨论 https://www.zhihu.com/question/19707376
- Stack Overflow 讨论 https://stackoverflow.com/questions/4163126/dereferencing-type-punned-pointer-will-break-strict-aliasing-rules-warning 消除警告不一定是变得不安全了,也可能是明确更安全了,可能的代价就是失去了潜在的优化机会。除了通过调用参数消除这个警告之外,可以给相关类型加上attribute((may_alias))。
- https://gcc.gnu.org/onlinedocs/gcc-4.0.2/gcc/Type-Attributes.html
消除warning方法小结
- 给相关类型加上attribute((may_alias))。
- 加编译选项 ,不进行严格检查 。-fstrict-aliasing 和 -Wstrict-aliasing
- void * 作为中间变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct ParaType{
int age;
bool gender;
...
};
//关键代码如下
char my_para[128];
void * tmp_ptr = my_para;
ParaType* my_para = reinterpret_cast<ParaType*>(tmp_ptr);
/*
* 作者:magicstone
* 链接:https://www.zhihu.com/question/19707376/answer/292424346
* 来源:知乎
* 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/
- 最终使用memcpy 替换 强制转换,达到相同的目的。