2010-11-14 17 views
5

Po programowaniu przez chwilę w C, postanowiłem w końcu zacząć uczyć się C++. To przeszkadza mi, ponieważ standardowy "hello world" w C to zwykle ~ 16 KB, w tym cały crud, który kompiluje tam twój kompilator. (Przy użyciu stdio)Skompilowane pliki wykonywalne C++ OGROMNE?

Jednak po utworzeniu pliku wykonywalnego C++ w świecie hello plik ma rozmiar ~ 470 KB! Posunąłem się naprzód i użyłem cstdio zamiast iostream, myśląc, że to coś zmieni.

Moje pytanie brzmi: Kiedy dołączam iostream, dlaczego rozmiar mojego pliku wykonywalnego eksploduje?

Edycja: używam g ++ (z Dev-CPP IDE, ale mogę dowiedzieć się, jak dodać CL paramaters)

+0

Chciałbym podkreślić, że Dev-C++ ma * bardzo * starą wersję GCC. Rozważ przeniesienie do wxDev-C++ lub Code :: Blocks, które są znacznie bardziej aktualne. – greyfade

Odpowiedz

6

Jednym słowem, symboli.

Biblioteka standardowa C++ wprowadza do programu symbole z symboli, ponieważ większość biblioteki istnieje głównie w plikach nagłówkowych.

Przekompiluj swój program w trybie zwolnienia i bez symboli debugowania, a możesz łatwo oczekiwać, że program będzie znacznie mniejszy. (. Mniejsze wciąż jeśli pasek symboli)

Jako szybki demonstracji tego faktu, należy przestrzegać:

$ cat hello.c 
#include <stdio.h> 
int main() { 
    printf("%s\n", "Hello, world!"); 
    return 0; 
} 
$ cat hello.cpp 
#include <iostream> 
int main() { 
    std::cout << "Hello, world!\n"; 
    return 0; 
} 
$ gcc hello.c -o hello-c 
$ g++ hello.cpp -o hello-cpp 
$ gcc hello.c -ggdb -o hello-c-debug 
$ g++ hello.cpp -ggdb -o hello-cpp-debug 
$ gcc hello.c -s -o hello-c-stripped 
$ g++ hello.cpp -s -o hello-cpp-stripped 
$ gcc hello.c -s -O3 -o hello-c-stripped-opt 
$ g++ hello.cpp -s -O3 -o hello-cpp-stripped-opt 
$ ls -gG hello* 
-rwxr-xr-x 1 6483 Nov 14 15:39 hello-c* 
-rw-r--r-- 1 79 Nov 14 15:38 hello.c 
-rwxr-xr-x 1 7859 Nov 14 15:40 hello-c-debug* 
-rwxr-xr-x 1 7690 Nov 14 15:39 hello-cpp* 
-rw-r--r-- 1 79 Nov 14 15:38 hello.cpp 
-rwxr-xr-x 1 19730 Nov 14 15:40 hello-cpp-debug* 
-rwxr-xr-x 1 5000 Nov 14 15:45 hello-cpp-stripped* 
-rwxr-xr-x 1 4960 Nov 14 15:41 hello-cpp-stripped-opt* 
-rwxr-xr-x 1 4216 Nov 14 15:45 hello-c-stripped* 
-rwxr-xr-x 1 4224 Nov 14 15:41 hello-c-stripped-opt* 

Nie potrafię wyjaśnić, dlaczego build Windows z programów z g ++ daje tak dużych plików wykonywalnych, ale na każdej innej platformie symbole są głównym czynnikiem wpływającym na duże rozmiary plików. W tej chwili nie mam dostępu do systemu Windows, więc nie mogę przetestować.

+1

+1! Możesz znaleźć ** lot ** symboli debugowania w STL. – jwueller

+0

Cześć, dziękuję za poświęcenie czasu na wyniki. Zrobiłem to w Windows używając flag "-s-O3", a rozmiar pliku zmniejszył się z 475kb do 263kb. Pomaga, ale czy mogę zrobić więcej? – Saustin

+1

@Sustustin: Użyj nowszego kompilatora. Używasz kogoś, kto jest * bardzo * stary. Prawdopodobnie pochodzi z niektórych cruft, które nie są wczytywane do nowszych wersji. Dev-C++ i tak jest nieużywany, więc nie ma powodu, aby go używać, gdy jest tyle innych, lepszych wyborów. Mam na myśli, najnowsze wydanie było w 2005 roku! – greyfade

7

ponieważ posiadał już przeciągnięty w większości biblioteki standardowej za pomocą iostreams. Jest to jednorazowa sprawa, ponieważ twoje programy stają się większe, a wyda się to coraz mniejsze.

Prawdopodobnie jednak chcesz skompilować bibliotekę ze wspólną biblioteką, a większość kompilatorów/systemów operacyjnych pozwoli ci to zrobić, więc nie będziesz musiał włączać całej standardowej biblioteki do pliku wykonywalnego. Z którego kompilatora korzystasz i możemy doradzić, jak to zrobić.

W oknach z wierszem poleceń VC użyj na przykład opcji wiersza poleceń/MD.

+0

Używam G ++ w \ Dev-CPP. – Saustin

2

Przypuszczam, że w tym <iostream> jesteś pośrednio w tym wiele części STL, takich jak <string> który z kolei obejmuje <vector> itp

+0

Aby umieścić tę odpowiedź w kategoriach C, jest to różnica między używaniem putc a printf. Kody printf mają wiele funkcji, które (względnie) sterują twoim plikiem wykonywalnym C w porównaniu z prostą funkcją putc. W przypadku Saustin, metody są "ogromne" w stosunku do printf, a STL jest "ogromny" w stosunku do . – franji1

2

Jest to bardziej artefakt kompilatora (i opcji), którego używasz, niż prawie wszystko. W MS VC++, w zależności od flag kompilatora, których używam, mogę uzyskać od ~ 8K do ~ 110K. Używając MinGW, otrzymuję około 24-25K (ponownie, w zależności od flag).

W przypadku, gdy zastanawiasz się, zgaduję, że większy zasięg, jaki uzyskuję dzięki VC++, to głównie w wyniku lepszego poznania flag. MinGW może dotyczyć tylko mniejszego zakresu, nawet jeśli wiedziałem o tym lepiej, ale z powodu mojej ograniczonej znajomości jego flag akceptuję większość tego, co robi domyślnie; Wiem, jak włączać i wyłączać optymalizację, ale muszę uważnie przyglądać się wszystkim, aby zrobić o wiele więcej.

1

MinGW (g ++) kompiluje naprawdę duże pliki.
Na przykład ten sam program "cześć świat" z kompilacją iostreams do ~ 100KB przez VC++ (z statycznie połączonymi CRT) i do ~ 470KB wg g ++.

+0

Jest to nadal prawdą w przypadku najnowszych programów Visual Studio i MinGW w-64 z GCC 7.2.0 (ze standardowymi flagami kompilatora używanymi przez CMake w wersjach Release). – clocktown

1

To jeden aspekt to faktycznie niby prawda :)

Wiesz, kiedy mieliśmy pierwszy kompilator C++, na co & T Skompilowałem „Hello World”, i mogłem nie wierzę w rozmiar pliku wykonywalnego. 2,1MB

Co? Odtąd kompilatory przeszły długą drogę.

Mają? Wypróbuj go na najnowszej wersji g ++ - nie dostaniesz zbyt dużej zmiany z pół megabajta.

+1

Niezbyt pomocne, ale pomaga humor. – Saustin

Powiązane problemy