2011-12-24 2 views
2

지난주 나는 웹에서 killallcops.exe이라는 간단한 게임을 발견했습니다. 바이너리를 연구하고 그 프로그램이 왜 그렇게 큰지 궁금해했습니다. (약 460K) 컴파일 된 바이너리의 크기는 사용 된 라이브러리에 따라 어떻게 달라 집니까? c/C++

그래서 나는 ++ g로 컴파일
#include <iostream> 
int main(){ 
    std::cout << "All cops are killed.\nCongratulations"; 
    std::cin.ignore(); 
    return 0; 
} 

를 iostream 사용하여 게임을 다시 썼다 너무 460K를 얻었다.

난 정말이 일이 이렇게 큰 이유를 궁금해하고 표준 입출력

#include <stdio.h> 
int main(){ 
    printf("All cops are killed.\nCongratulations"); 
    while(getchar() != '\n'){} 
    return 0; 
} 

는 GCC와 함께 컴파일 13K있어 사용하여 다시 썼다.

iostream은 stdio (typesafety와 같은)보다 훨씬 더 많은 능력을 가지고 있기 때문에 그 자체가 훨씬 크기 때문에 더 큰 바이너리를 생성하고 iostream을 사용할 때 크기를 줄이는 해결책이 있는지, 예를 들어 특정 그 부분들?

편집 : 나는 리눅스에서 재생하지 못하는 Cygwin에서

+0

하나의 추측 : 템플릿. –

+0

컴파일 할 어셈블리를 보여줄 수 있습니까? –

+2

''은 간단한'cout' 호출을 사용하는 경우에도 많은 내부 의존성을 가지고 있습니다. 그것은 (템플릿 코드 등을 포함하는) 많은 코드/헤더를 필요로합니다. 컴파일러/링커가 자신이하는 일을 알 수 있지만 바이너리 크기를 줄이려면 심볼을 제거하는'gcc -s' 나 최적화를 시도하는'-Os'와 같은 옵션을 사용 해보십시오 사이즈의 바이너리 그러나 중요하지 않은 응용 프로그램에서는 ''을 가져 오는 크기가 그다지 중요하지 않습니다. – birryree

답변

3

나는 대답으로 내 댓글에 살 수 있습니다 :

<iostream> 내부의 많은이를 심지어 간단한 cout 호출을 사용하는 경우에도 마찬가지입니다. 그것은 (템플릿 코드 등을 포함하는) 많은 코드/헤더를 필요로합니다. 앞쪽에는 <iostream>을 가져 오는 크기가 중요하지 않은 응용 프로그램에서는별로 중요하지 않다고 가정 해 보겠습니다.

당신은 그들이 무엇을하고 있는지 알고 컴파일러/링커를 신뢰하지만 바이너리 크기를 줄이려면의 바이너리를 최적화하기 위해 시도 -Os 같은 기호 또는 플래그 스트립하는 gcc -s 같은 옵션을 사용하여 시도 할 수 있습니다 크기.

정적으로 링크 된 libstdc++의 바이너리 크기 문제가 실제로 다른 것에서 비롯된 것으로 의심됩니다.

Windows에서 MinGW를 사용하는 경우 매우 최근까지는 GCC 툴체인의 구현에 동적으로 연결된 libstdc++이 없었습니다. 대신 모든 C++ 빌드는 바이너리의 크기를 크게 늘릴 수있는 libstdc++에 정적으로 링크됩니다.

다음은 GCC 4.6.1을 사용하여 리눅스에서 코드에 대해 g++에 의해 생성 된 바이너리 크기를 비교 한 것입니다.이 빌드에서는 최적화 또는 기호 제거가 수행되지 않았습니다.

λ > ls -lh a.out   
-rwxr-xr-x 1 billylee billylee 6.1K Dec 24 10:37 a.out 

그리고 여기가 GCC

λ > ls -lh trial 
-rwxr-xr-x 1 billylee billylee 4.9K Dec 24 10:41 trial 

g ++ 버전은 버전의 gcc보다 약간 큰 제작 한,하지만 100 배 더 크다.

편집 : - : How to reduce the size of executable produced by MinGW g++ compiler?

는 MinGW gcc를 4.5.0+이는 MinGW를 사용하는 경우 버전을 확인, 기본적으로 동적 링크를 사용해야합니다 당신이는 MinGW를 사용하는 경우 여기에 최근의 스레드가있다.

+0

네, cygwin gcc를 사용하고 있다는 것을 잊어 버렸습니다. 그냥 체크, 버전 3.4.4 내가 업데이 트하고 나중에 다시 확인합니다. 설명 해줘서 고마워. – Baarn

+0

cygwin gcc를 업데이트하는 것이 더 큰 문제 였지만 대학용 리눅스 박스에서 시도해 보았습니다. (저의 며칠 전 감광 시켰습니다) 비슷한 결과를 얻었습니다. 감사 – Baarn

2

에서 GCC 3.4.4를 사용하여 아래에 명시된 바와 같이 (크기가 9K 및 8K이다). 내 생각 엔 C++의 경우 표준 라이브러리를 정적으로 링크하는 반면 C는 동적으로 링크하는 것입니다.

2

답변은 다음과 같습니다. 컴파일 옵션이없는 Linux의 C++ 4.6에서 컴파일 된 것은 9040 바이트입니다. 스트립 후 6312 바이트입니다.

어떤 컴파일 옵션을 사용하고 어떤 g ++ 버전을 사용하고 있습니까?

크기가 플랫폼 때문일 수 있습니다. 예를 들어 MinGW를 사용하고 있고 런타임에 정적으로 링크하는 경우 일 수 있습니다. 보조 노트에

#import가되지 g ++ 언어 만 확장, 당신은 사용해야 #include

+0

사실, 지난 며칠 동안 너무 많은 자바를 사용했기 때문에 내 메모리에서 코드를 작성할 때 오류가 발생했습니다. – Baarn

+0

@left 만약 내가 기억한다면 기본적으로 리눅스에서 컴파일 할 때 rtl은 윈도우에서와 같이 정적으로 링크되지 않는다. 물론 그것은 더 작아 질 것입니다. 그것은 똑같은 비교가 아닙니다. – greatwolf