2014-06-05 119 views
0

我发现,我已经在几年前实施的,以及它的编译的二进制可执行文件的旧的C源代码。相同的C源,不同的输出

在评论我写的编译命令是:

gcc -O3 source.c -o executable -lm 

所以我重新编译,但新的可执行文件是从旧的不同(大小)。

在我办了新的和旧的可执行文件,他们给了我不同的结果的事实:老的可执行文件返回相同的结果年前回来了,而新的返回不同的结果。

我的目标是能够重新编译源代码并获得与旧的(或至少一个可生成完全相同结果的可执行文件)相同的可执行文件。

我敢肯定,我运行两个程序使用相同的参数,并且该代码不会使用线程可言。唯一特别的是我需要随机整数,但我使用自己的函数来产生它们以防止随机数序列总是相同的(当然我总是使用相同的种子)。

unsigned int seed = 0; 
void set_srand(unsigned int aseed) { 
    seed = aseed; 
} 

int get_rand() { 
    seed = seed * 0x12345 + 0xABC123; 
    int j = (seed >> 0x10) & RAND_MAX; 
    return j; 
} 

(我以为这是从一些图书馆复制)。

那么它会是什么?也许在编译完成的OS(原之一是在WinXP下,现在我想双方的Win7和Ubuntu下),但我一直只用MinGW的。那么也许MinGW的版本?如果是这样的话,我会陷入困境,因为我不记得几年前我使用过哪个版本。

图书馆,我用:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 

我不只是字符串操作和计算像pow()sqrt(),乘,加/减,为了应用启发式优化算法来近似求解的NP-难题:结果都是问题的解决方案,但是它们的适应性是不同的。

+0

你能分享一下你的程序产生的输出类型吗?以及版本之间的差异究竟如何? – MultiVAC

+0

听起来像代码中的错误。依靠未定义的或实现特定的行为? – user694733

+0

如果您需要相同的可执行文件,请使用您用于旧版本的相同版本的编译器。如果你的程序是确定性的,但你得到了不同的结果,那么它会暗示其中一个编译器被窃听(不太可能),或者你自己的代码有未定义的行为。旧的可执行文件是否使用调试符号编译?尝试在调试器中运行并查看执行发散的位置。(哎呀,只是注意到命令是在问题中,运气不好) – user2079303

回答

1

我会检查的第一件事是int的长度。你的代码依赖于溢出,整数的大小可能很重要。

您的代码似乎在暗示,int是至少32位(您使用0x0x269EC3),但也许你现在正在为int在64位编译。

我就不会担心的可执行文件,这是非常不可能的,你用两个不同的编译器得到相同的尺寸。

+0

不,没有“溢出”。算术是'unsigned int',它被定义为产生一个特定的结果,以二次幂次幂为模。我无法想象OP会不小心切换到64位。这不是。 –

+0

我没有说这是一个未定义的行为。 'unsigned int'情况下的溢出行为取决于大小。我正是这个意思。 –

+0

我也没有。我说没有'溢出'。该标准明确指出(引号)'无符号算术不会溢出'。是的,结果取决于规模,但“溢出”仍然没有任何与它有关的事情。 –