2014-06-05 5 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; 
} 

(일부 라이브러리에서 복사 한 것 같습니다.)

그래서 무엇이 될 수 있습니까? 어쩌면 컴파일이 완료된 운영 체제 (원래 WinXP에서 WinXP 아래에 있었는데 이제는 Win7과 Ubuntu에서 모두 사용하고 있습니다), 항상 사용했습니다. MinGW. 아마 MinGW 버전일까요? 이 경우 몇 년 전에 어떤 버전을 사용했는지 기억하지 못하기 때문에 문제가 있습니다. 내가 사용하는

라이브러리 :

내가 pow(), sqrt(), 곱셈과 플러스/마이너스 같은 단지 문자열 연산과 계산이 대략적 NP-를 해결하기 위해 휴리스틱 최적화 알고리즘을 적용하기 위해서입니다 무엇을
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 

어려운 문제 : 결과는 문제의 해결책이지만 문제는 두 가지입니다.

+0

프로그램에서 생성하는 출력 유형을 좀 더 공유 할 수 있습니까? 정확히 버전간에 어떻게 다른가요? – MultiVAC

+0

코드에 버그가있는 것 같습니다. 아마도 정의되지 않은 구현 또는 구현 특정 동작에 의존하고 있을까요? – user694733

+0

동일한 실행 파일이 필요하면 이전 버전과 동일한 버전의 컴파일러를 사용하십시오. 프로그램이 결정적이지만 다른 결과를 얻는다면 컴파일러 중 하나가 도청 당했을 가능성이 높거나 자신의 코드에 정의되지 않은 동작이 있음을 알 수 있습니다. 디버거 기호로 컴파일 된 이전 실행 파일입니까? 디버거에서 실행 해보고 실행이 갈라지는 곳을 확인하십시오. – user2079303

답변

1

먼저 확인해야 할 것은 int 크기입니다. 귀하의 코드는 오버플로에 의존하고 정수의 크기는 중요 할 수 있습니다.

코드가 int가 최소 32 비트 (0x0x269EC3을 사용)이지만 암시 적으로 64 비트로 컴파일하고있는 것 같습니다.

저는 실행 파일에 대해 걱정하지 않으려 고합니다. 두 개의 다른 컴파일러가 같은 크기를 얻지는 않을 것입니다.

+0

아니요, '오버플로'가 없습니다. 산술 연산은 'unsigned int'이며, 다음 결과로 2의 큰 값을 모듈로 출력하도록 정의됩니다. 그리고 OP가 우연히 64 비트로 전환된다고 상상할 수는 없습니다. 이것은 아닙니다. –

+0

정의되지 않은 동작은 아닙니다. 'unsigned int'의 경우 오버플로의 동작은 크기에 따라 다릅니다. 그것이 내가 의미했던 것입니다. –

+0

나도 마찬가지입니다. 나는 '넘칠 것'이 없다고 말했습니다. 표준에 따르면 '부호없는 산술이 오버플로하지 않음'이 명시 적으로 명확합니다. 예, 크기에 따라 결과가 달라 지지만 '오버플로'에는 아무 관계가 없습니다. –

관련 문제