个人网站制作在线,pc网站建设的优势是什么,营销运营管理,坪山网站建设哪家好文章目录 前言没有警告不代表没有问题目前的应对方法 前言
很久没写了#xff0c;水一篇。
最近有个代码在gcc 4.8.5上编译失败。编译失败的提示是#xff1a;
error: dereferencing type-punned pointer will break strict-aliasing rules [-Werrorstrict-aliasing]查了下… 文章目录 前言没有警告不代表没有问题目前的应对方法 前言
很久没写了水一篇。
最近有个代码在gcc 4.8.5上编译失败。编译失败的提示是
error: dereferencing type-punned pointer will break strict-aliasing rules [-Werrorstrict-aliasing]查了下这个报错有点复杂。大体是不要使用一个类型的指针去操作另一种指针指向的空间。比如下面这样
#include inttypes.h
#include stdio.hstruct internet {__uint16_t ip;
};__uint8_t address[10];int main(int argc, char *argv[]) {address[0] 1;address[1] 2;struct internet *net (struct internet *)address;__uint16_t ip net-ip;printf(% PRIu8 \n, address[0]);printf(% PRIu8 \n, address[1]);printf(% PRIu16 \n, ip);
}然而上面这段代码在不同的gcc 11.4.1版本下编译没有问题。
关于Strict Aliasing Rule的详细解释见What is the Strict Aliasing Rule and Why do we care?、c when would you not want to use strict aliasing?
我也没有完全搞懂。下面示例来自这个链接。 没有警告不代表没有问题
下面我们来看下这个示例。在常见的gcc版本下编译都能复现。
#include iostreamint foo(float *f, int *i) {*i 1;*f 0.f;return *i;
}int main() {int x 0;std::cout x std::endl; // Expect 0int x_ret foo(reinterpret_castfloat *(x), x);std::cout x_ret \n; // Expect 0?std::cout x std::endl; // Expect 0?
}首先我们编译的时候不要开启优化输出如下
g -O0 demo-2.cpp -o demo-20
0
0接着我们编译的时候开启优化输出如下
g -O2 demo-2.cpp -o demo-20
1
0这就比较脑壳痛了。日常开发编译的是debug版本它没有优化。发布的时候编译的是release版本它有一定的编译优化。然后相同的代码debug和release版本的运行不同。这个问题可能就很难排查。
为什么会出现这种情况编译器也没有给出警告
大概是因为优化的时候编译器看到要返回的是i和f又没有什么关系给返回寄存器里面提前填入了i的值。 目前的应对方法
一般来说日常编程中即使不同类型的指针操作相同的内存也不会出现上面这种情况。所以正常使用就好不用特地回避出问题再解决问题。为什么不事先回避这个问题呢因为搞不清那就先不管。
如果遇到上面这种问题或者因为这个问题编译失败怎么办呢
第一种方法是使用memcpy进行拷贝不要直接使用不同类型的指针操作相同的内存。第二种方法是在gcc的构建选项中添加-fno-strict-aliasing选项。但是这会导致整个构建过程都忽略了这个限制。第三种是可以尝试下使用__attribute__((optimize(-fno-strict-aliasing)))修饰函数但是这不一定有效。