文档章节

warning: dereferencing pointer ** does break strict-aliasing rules

mi616
 mi616
发布于 2017/02/06 10:02
字数 801
阅读 55
收藏 0

记录一次编译开启优化导致的错误

错误提示如下,实际是个警告,但是由于编译器在警告出进行了优化,最后导致了严重的错误:
中文警告:提领类型双关的指针将破坏强重叠规则
warning: dereferencing pointer ‘p’ does break strict-aliasing rules


警告产生背景:

警告是在进行代码移植时遇到的,原代码运行在32位系统,并且gcc版本较低,具体是哪一版本不知道,接手代码后我直接开始移植到64位系统,gcc版本4.4。
经过漫长的修改不得不吐槽一下,移植有多蛋疼,比如之前的代码很多指针强转为32位整型,要3000多行代码一行一行检查类型改成64位的,同时修改后的代码还要兼容32位。
移植代码问题不说,主要针对这个警告,在移植过程中,我在两个系统中测试过代码,一个是win10系统带的bash,Ubuntu14.04的内核,GCC版本4.8.4,另一个是开发环境Linux系统,GCC版本4.4。在Bash on Ubuntu on Windows下编译运行没问题不会警告,运行正常。在开发环境下会出现警告,程序运行进入死循环。
后来发现,Makefile里面加了-O2优化。这种莫名其妙的问题检查了一天代码没发现原因,估计可能是编译器优化的问题,毕竟这个代码是32位老系统移植过来,编译出现问题是非常有可能,所以取消-O2优化,编译通过,没有警告,运行正常。

警告分析:

该警告出现的情况是,两个不同类型(size不同)的指针指向了同一内存区域,很明显出现这种问题必然是有错误的,这个和类型强制转换应该是不同的。
uint64_t sum = 0;
uint32_t *sum_p = (uint32_t *)∑
sum本身是64位变量,sum_p指针又是指向32位变量,就出现同一个起始地址对应两个类型长度不同的变量。编译器优化会对这个地方做处理,具体处理不明。

警告处理:

处理方法很简单,错误代码的目的很明显:    
uint64_t sum = 0;
uint32_t *sum_p = (uint32_t *)∑
开发者想法应该是使用sum_p去分别读取64位sum的前后32字节数据,sum_p[0], sum_p[1]比如这样,这种运用在大数加法中常用到,两个1024位大数进行加法,以32位为基准进行循环加法,每次相加可能会有进位操作,和保存在64位中,不会溢出,同时能提取进位后的值进行后续的加法运算。
总之错误代码目的就是把一个64位整型,分成前后两个32位整型分别读取。
这听起来和C语言联合体功能一样,的确,解决办法就是使用联合体:
union sums
{
    uint32_t sum_p;
    uint64_t sum;
};
union sums add;
add.sum = val;
add.sum_p自然就是前32位,将add.sum移位就可以得到后32位。

© 著作权归作者所有

共有 人打赏支持
mi616
粉丝 0
博文 5
码字总数 6126
作品 0
东城
程序员
私信 提问
在macbook下安装pysqlite求教

我在mac ox 10.12下用pip install pysqlite,结果出现以下错误信息,请大牛帮我看看,多谢多谢! Collecting pysqlite Using cached pysqlite-2.8.3.tar.gz Installing collected packages: ......

PochaccoX
2017/03/01
236
3
error: dereferencing pointer to incomplete type

ccj@ubuntu :~/workspace/process/proconver/shm$ gcc shm1.c -o shm1 shm1.c: In function ‘main’: shm1.c:46:15: warning: assignment from incompatible pointer type [enabled by defa......

ccjzb
2014/05/01
945
4
C/C++ Strict Alias 小记

什么是Aliasing? 理解strict aliasing一文中这样描述: 当两个指针指向同一块区域或对象时,我们称一个指针 alias 另一个指针。 strict aliasing一文中这样描述: Aliasing 是指多于一个的左...

晨曦之光
2012/05/08
361
0
python3.4安装uwsgi的时候提示我openssl有问题,有人能帮忙看一下吗?

Debian GNU/Linux 8.4 (jessie) 安装python3.4的uwsgi 包编译失败。 workon python3.4的虚环境上(实际上python2.7,python3.4的非虚环境也是装不上的) openssl是1.1.0c =========== pip in...

daine199
2017/01/03
730
0
squid install script

#!/bin/sh if [ getconf LONG_BIT == 32 ];then export CHOST="i686-pc-linux-gnu" export CFLAGS="-O9 -funroll-loops -Wall -W -mtune=nocona -mcpu=nocona -march=nocona -mfpmath=sse -p......

企图穿越
2010/06/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

pg_lightool基于basebackup的单表恢复和块恢复

开源软件pg_lightool,实现了基于wal日志的块恢复。详情参见博客:https://my.oschina.net/lcc1990/blog/1931485。由于wal日志中FPW的不确定性,它不能作为一个数据库恢复的解决方案。目前对...

movead
17分钟前
2
0
对比剖析Swarm Kubernetes Marathon编排引擎

Docker Native Orchestration 基本结构 Docker Engine 1.12 集成了原生的编排引擎,用以替换了之前独立的Docker Swarm项目。Docker原生集群(Swarm)同时包括了(Docker Engine \/ Daemons)...

Linux就该这么学
18分钟前
1
0
Mybatis的结果集处理

此时我们已经可以把整段的SQL语句取出,但还并没有在数据库中去执行,我们可以先来分析一下配置文件中SQL语句执行后的结果集是如何处理的。 Mybatis会将结果集按照映射配置文件中定义的映射规...

算法之名
30分钟前
16
0
Spring Boot(Spring的自动整合框架)

Spring Boot 是一套基于Spring框架的微服务框架,由于Spring是一个轻量级的企业开发框架,主要功能就是用于整合和管理其他框架,想法是将平时主流使用到的框架的整合配置预先写好,然后通过简...

花漾年华
33分钟前
2
0
Windows下条件变量的实现

条件变量是什么? 是一种同步对象。 条件变量有什么用? 用于复杂的、多线程的、多核的程序中,实现多个线程间同步任务。 条件变量与其它同步对象的区别? 与事件、互斥锁、segment等同步对象...

shzwork
35分钟前
1
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部