存档

文章标签 ‘gcc’

编译检查应用

2010年8月7日 没有评论

一个升级项目里,需要更改帐号体系,简单的说,就是帐号体系由32位帐号体系切换到另一部门的64位体系。系统里面一般都会对id类型做定义:typedef user_id_t uint32_t;看起来是个简单任务,只需要更改一下typedef user_id_t uint64_t,就可以完成。但实际情况远非如此。比如数据固化层需要扩充字段类型,再比如为了应付大访问量,某些服务会采用bitmap的形式在内存中维护数据,在64位体系下需要修改内存数据组织方式。

涉及底层体系的升级,牵一发而动全身,但本文只关注一个很小的问题,变量size。我们考虑以下场景 :

1. 并不会所有地方,程序员都用typedef,假如存在这样的代码段:

userid_t id_a;  // typedef后此处为64位

//....code....

uint32_t id_b;
id_b = id_a;

我们会发现赋值后,数据精度会丢失。这个错误可以通过加-Wconversion参数来警告。

2. 如果原有函数接收32位数据,但实参id已经是64位了:

// ErrorCode 1
pPacket->id = htonl(id)

// ErrorCode 2
void foo( uint32_t id )
{
    // ...code...
}

foo( id )

在上面的例子中,数据传递过程高32位数据丢失。类似的代码如果有一处遗漏,功能方面就会出问题,增加调试和定位的工作量。

这样的错误,比较适合用编译器检查。但gcc4.3以后才支持检查此错误,而公司所广泛使用的gcc版本是3.4。(实际也尝试过用lint工具,但由于报的错误太多而放弃)。

第一步 编译安装:

比起升级glibc,升级gcc相对简单,上官网下载了一个gcc 4.3,基本按照常规的步骤即可完成。

由于gcc与硬件平台相关,就不给出具体参数了,玩过交叉编译的同学估计都很熟悉。如果对gcc编译不熟练的,注意下configure时,一是要选对host,让gcc可以正确的生成代码,如果不知道机器的host类型,可以查看现有的gcc编译参数,也可以在/usr/include目录下找到;另外,一定要加disable-multilib,这样就只会为本机产生代码。

第二步 gcc切换

由于我们只用gcc4做语法检查,真正生成代码还是由gcc3完成,因此,需要两个环境可以简单切换。需要注意的是,仅仅通过改PATH变量,还是不够的,还需要更换指向的header/so。

第三步 过滤boost错误信息

升级后,使用新版的gcc编译时,会发现boost有大量的警告,非常烦人。其中有一部分,像this指针的shadow定义,可以通过相应的选项-Wno-xxx去掉,有一些是无法去除的;就算可以显式通过选项指定,但有可能这些检查是我们所需要的。因此,我修改了出错显示代码,在打错出错信息的时候,检查一下调用栈,如果最底层(也就是出错的地方)的路径是boost目录,直接return。重新编译后,boost错误信息就被过滤掉了。

完成了这几步,我们的目的就基本达成了,可以做赋值size编译检查,过滤了boost信息,并且可以和vim等编译器结合。

分类: 未分类 标签: