在无头绪时,将代码纳入以前写的工程库在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日,中午