Compiled C++ executables HUGE?
Asked Answered
N

6

6

After programming for a while in C, I decided to finally start to learn C++. This is sort of bothering me, as the standard 'hello world' in C is usually ~16KB, including all of the crud your compiler throws on there. (Using stdio)

However, when I create a C++ executable doing hello world, the file is ~470KB! I went ahead and used cstdio instead of iostream, thinking it would make a difference and it did.

My question is: When I include iostream, why does the size of my executable explode?

Edit: I'm using G++ (With the Dev-CPP IDE, but I can figure out how to add CL paramaters)

Nil answered 14/11, 2010 at 18:21 Comment(1)
I'd like to point out that Dev-C++ comes with a very old version of GCC. Consider moving to wxDev-C++ or Code::Blocks, both of which are far more up-to-date.Meenen
M
7

In a word, symbols.

The C++ standard library introduces a lot of symbols to your program, since most of the library exists primarily in the header files.

Recompile your program in release mode and without debug symbols, and you can easily expect the program to be significantly smaller. (Smaller still if you strip symbols.)

As a quick demonstration of this fact, observe:

$ 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*

I can't explain why a Windows build of the programs with G++ produces such large executables, but on any other platform, symbols are the primary driving factor in large file sizes. I don't have access to a Windows system at the moment, so I can't test.

Meenen answered 14/11, 2010 at 18:35 Comment(4)
Hi, thanks for taking the time to do the results. I did this in windows using the '-s -O3' flags, and the file size reduced from 475kb to 263kb. It helps, but is there any more I can do?Nil
@Saustin: Use a newer compiler. You're using one that's very old. It probably comes with some cruft that doesn't get globbed onto the newer versions. Dev-C++ is unmaintained anyway, so there's no reason to keep using it when there are so many other, better choices. I mean, the most recent release was in 2005!Meenen
This is true; are there any compilers that you would happen to recommend? (PS: Sorry for the long time to verify!)Nil
@Saustin: The version of MinGW packaged with Code::Blocks is up to date. The one packaged with wxDev-C++ (which isn't the same as what you're using) is up to date. You can also use Visual Studio 2010 Express which is also up to date.Meenen
P
6

Becuase you've dragged in most of the standard library by using iostreams. It's a one off thing though so as your programs gets larger it will seem less and less of an overhead.

However you probably want to compile using a shared library version of the standard library and most compilers / operating systems will let you do this so you'll not have to include all of the standard library in your executable. Which compiler are you using and we can likely advise on how to do that.

On windows with VC command line, use the /MD command line option for example.

Phelps answered 14/11, 2010 at 18:25 Comment(0)
T
2

I would guess that by including <iostream> you're indirectly including many parts of the STL, such as <string> which in turn includes <vector> etc.

Typography answered 14/11, 2010 at 18:25 Comment(1)
To put this answer in C-terms, it's the difference between using putc vs. printf. printf code has a LOT of functionality that (relatively) boats your C executable vs. a simple putc function. For Saustin's situation, <iostream> methods are "huge" relative to printf, and STL is "huge" relative to <iostream>.Berberine
S
2

This is more an artifact of the compiler (and options) you use than almost anything else. With MS VC++, depending on the compiler flags I use I can get anywhere from ~8K to ~110K. Using MinGW, I get around 24-25K (again, depending on flags).

Just in case you're wondering, I'd guess the larger range I get with VC++ is mostly a result of knowing its flags better. MinGW might only cover a smaller range even if I knew it better, but due to my limited knowledge of its flags I'm accepting most of what it does by default; I know how to turn optimization on and off, but have to look at things pretty carefully to do a lot more than that.

Sleep answered 14/11, 2010 at 19:18 Comment(0)
G
1

MinGW (g++) compiles really big files.
For example the same "hello world" program with iostreams compiles to ~100KB by VC++ (with statically linked CRT) and to ~470KB by g++.

Gestation answered 14/11, 2010 at 19:39 Comment(1)
This is still true with the newest Visual Studio and MinGW w-64 with GCC 7.2.0 (with the standard compiler flags that CMake uses for Release builds).Ballista
S
1

This is one aspect of the fake C++ interview that is actually kind of true :)

You know, when we had our first C++ compiler, at AT&T, I compiled 'Hello World', and couldn't believe the size of the executable. 2.1MB

What? Well, compilers have come a long way, since then.

They have? Try it on the latest version of g++ - you won't get much change out of half a megabyte.

Sold answered 14/11, 2010 at 22:52 Comment(1)
Not really helpful, but some humor helps.Nil

© 2022 - 2024 — McMap. All rights reserved.