当前位置: 首页 > 代码生活 > 正文

遇到一个gcc编译器版本导致的运行结果有差异的问题

正在进行的项目中有个网络模块,需要在上位机将数据包加密,然后在设备端将数据包解密。两者使用的加密方法是可逆的(大概是异或之类的)。在我测试时,发现设备上解出来的数据不正常,得不到上位机未加密前的数据。因为这个模块在其它项目一直使用,一直OK,现在出问题了,很郁闷。而且该模块嵌入到其它大的功能模块,后来将加密、解密模块独立出来测试。当定位到解密这个点上,都已经过了大半天了。
在无头绪时,将代码纳入以前写的工程库在VS中测试,发现一切正常。结论是windows编译后运行结果正确,但linux却不正确,这又让我郁闷了。后来又试了不同的linux,结果有的成功,有的还是有错误。再细查,原来所用的gcc版本不同导致运行结果不同。在最新的4.8版本中,解密后的数据不对,但在4.6版本却是正确的。

核心的代码实际上使用了宏定义,示例如下:

#define M_NUM 0xdeadbeef
#define XOR(m1, m2, m3) (m1*M_NUM^m2^m3)
#define FOOBAR(f, u, c, k) (f ^ XOR(u,c,k))

单从代码上,我无法解释为什么在不同的gcc得到的结果不同。在我的知识水平范围内,我无从修改代码,姑且认为是编译器的问题(代码有问题赖编译器可不是好习惯)。既然是编译器版本的差别,只能曲线找方法。我的方法是将实现加密、解密的文件单独使用4.6版本的gcc编译成lib,然后其它代码模块调用这个库的函数,这样避免了用高版本的编译器编译所有文件。事实说明,这样的可行的,虽然方法在专业人士或领导眼中不屑一顾,但我不说,又有谁会遇到这种问题呢?我又岂能为了这个小模块而将移植好的内核、驱动、根文件系统工具重新使用4.6版本的gcc编译过一次呢?

2015.10.19的PS:
如今因为修正另外的代码分支代码警告而遇到这个代码片段,在VS2010、gcc4.4、gcc4.8上的编译结果均不相同。经仔细揣摩仅的几行语句,发现是同一语句对同一变量进行多次运算造成的未定义行为。示例代码:

*ptr++ = FOOBAR(*ptr, f, u, c);

类似学校经常考的i=i++这种题目。这种语句的结果因编译器不同而不同。编译器警告提示为:

warning: operation on ‘ptr’ may be undefined [-Wsequence-point]

有兴趣的可以搜索一下sequence-point这个关键词,网上有很多资料。
李迟,2015年1月17日,中午

本文固定链接: http://www.latelee.org/code-life/gcc-version-problem.html

遇到一个gcc编译器版本导致的运行结果有差异的问题:目前有1 条留言

  1. 1楼
    zfy1989lee:

    跟你一个效果,我要跑别人的一个2005年的程序, 用新的gcc完全不能正确。还原到我之前用的gcc 4.6.3就OK了

    2015-03-16 下午11:50 [回复]

发表评论

*

快捷键:Ctrl+Enter