I am amased...

Programming, for all ages and all languages.
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

I am amased...

Post by Zacariaz »

Little did i know that the difference between C and C++ was this great.
I made two hello world programs

In C

Code: Select all

#include <stdio.h>

int main() {
  printf( "I am alive!  Beware.\n" );
  getchar();
  return 0;
}
and in C++

Code: Select all

#include <iostream>

int main() {
  std::cout << "I am alive!  Beware." << std::endl;
  std::cin.get();
  return 0;
}
Seemingly they are the same (im not 100% sure of it) but the difference in size after compiled is huge 15.4KB vs. 463KB

My plan was to take a look at the debug code, but 463 is to much for me, so i was thinking if anyone could explain a litle about where the differences lye, and allso if the two pieces of code are really as close to each other as you get.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

The main difference is here:
Zacariaz wrote:

Code: Select all

#include <iostream>
If you remove that line it drops to around 16 kB.

I guess the iostream header includes many, many more.

Although compiling the C version with g++ does add 1015 bytes to it over the output of gcc.

Regards,
John.
senaus
Member
Member
Posts: 66
Joined: Sun Oct 22, 2006 5:31 am
Location: Oxford, UK
Contact:

Post by senaus »

That's probably because of all the bloated STL code being linked in. I converted my kernel to C++ recently and the code size hardly changed, it's the libs that add the bloat!

Code: Select all

-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M/MU d- s:- a--- C++++ UL P L++ E--- W+++ N+ w++ M- V+ PS+ Y+ PE- PGP t-- 5- X R- tv b DI-- D+ G e h! r++ y+
------END GEEK CODE BLOCK------
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Post by Zacariaz »

ok, im no super programmer, but i didnt actually think it included the whole header.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

Zacariaz wrote:ok, im no super programmer, but i didnt actually think it included the whole header.
You're right, but somewhere in that huge mess of includes it references there's probably a pragma to include a library or two. Just have to find it...
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Post by Zacariaz »

K, but the main thing, i guess, is that C is much better at handling those headers than C++? Or is that the wrong impression?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

Zacariaz wrote:K, but the main thing, i guess, is that C is much better at handling those headers than C++? Or is that the wrong impression?
That's very wrong yep.

C includes no static objects, no long function names (only required 32 characters to work for that matter) and so on. C++ requires static object (std::cout is a static object of a complex type, std::cerr is an object) and much longer names for the variables since they're in namespaces and need to be kept out of the C name space. It also commonly includes a lot of standard support for things your application might receive depending on the environment, such as exception handling and run-time type identification. You also probably include a bit of debug or such. Look at the object with objdump and find out what's what exactly - try looking at the section headers mostly, they tell you how big each part is.

Compiling the C application with the C++ compiler makes it mangle the names as C++ would do. I compile my entire kernel with the c++ version to take advantage of overloading.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

I can't reproduce your behaviour here:

-rwxr-xr-x 1 candy users 8134 2007-05-29 20:40 hello*
-rw-r--r-- 1 candy users 98 2007-05-29 20:40 hello.c
-rwxr-xr-x 1 candy users 10628 2007-05-29 20:40 hello2*
-rw-r--r-- 1 candy users 118 2007-05-29 20:40 hello2.cc

After stripping:

-rwxr-xr-x 1 candy users 2956 2007-05-29 20:42 hello*
-rw-r--r-- 1 candy users 98 2007-05-29 20:40 hello.c
-rwxr-xr-x 1 candy users 4652 2007-05-29 20:42 hello2*
-rw-r--r-- 1 candy users 118 2007-05-29 20:40 hello2.cc
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Post by Zacariaz »

Ok, i think i more or less get it, however one question still remains.
I am using the dev-c++ compiler (bloodshed ide) would it makes a notisable difference using a c compiler instead?

And thanks for the answers.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

begin with setting the "strip executable" option to yes. That will probably save you more than switching to C. Its in Project -> Project Options -> Compiler tab -> Linker.

In my case, it shrank a small opengl test app from 419k to 11k (just tested)

@Candy: Windows obviously isnt linux...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

My figures were with MinGW. I stripped the C++ version, but it still came to over 200kB. Running nm on it shows just how much stuff is needed just to run this program.
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Post by Zacariaz »

wow, that did make a difference, thanks alot.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Some more words on this. I am using Cygwin GCC 3.4.4.

Code: Select all

#include <stdio.h> 

int main() { 
  printf( "I am alive!  Beware.\n" ); 
  getchar(); 
  return 0; 
}
Unstripped 9167 bytes, stripped 3072 bytes.

Code: Select all

#include <cstdio> 

int main() { 
  std::printf( "I am alive!  Beware.\n" ); 
  std::getchar(); 
  return 0; 
}
Unstripped 9014 bytes, stripped 3072 bytes.

Finding #1: Just running GCC in C++ mode doesn't add to the binary size.

Code: Select all

#include <cstdio>
#include <string>

int main() { 
  std::printf( "I am alive!  Beware.\n" ); 
  std::getchar(); 
  return 0; 
}
Unstripped 9014 bytes, stripped 3072 bytes.

Finding #2: Adding a C++ header does not add to the binary size.

Code: Select all

#include <iostream>
#include <cstdio>

int main() { 
  std::printf( "I am alive!  Beware.\n" ); 
  std::getchar(); 
  return 0; 
}
Unstripped 477999 bytes, stripped 276992 bytes.

Whoa, what happened there?

The answer is: Global objects (as Candy said).

The C subset example didn't need to link anything C++-specific. But <iostream> gives you cin and cout (and cerr and clog and the wide-character counterparts), which have to be initialized no matter whether you use them or not. This in turn requires the supporting C++ runtime: Global constructor calling and exception support, mostly.

"Yuck, why should I use C++ then?"

The answer is threefold.

One, most of this is a one-time cost. We are not looking at a size factor of 100 here, but a fixed cost of 200k supporting code. For any non-trivial application, the cost of exception support in code size is neglectable compared to the application proper. With good C++ code, you will actually reach a break-even point pretty soon where the C++ exception support is smaller than the code required in C to check each and every return code.

Two, if you don't want to use the library or exceptions, you can simply disable them altogether. It's all about choice.

Three, abstraction. I'll let code speak for me here.

Code: Select all

cout << x; // print x regardless of what type it is. Try this in C.
Every good solution is obvious once you've found it.
User avatar
AndrewAPrice
Member
Member
Posts: 2303
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

You can include stdio.h in C++ and use printf. But 463KB for a C++ Hello World and 15.4KB for C? That doesn't sound right. Everything which runs in kernel mode in my OS is written in C++ and it's only 16KB.
My OS is Perception.
Twitch
Member
Member
Posts: 40
Joined: Mon Jun 04, 2007 6:29 pm

Post by Twitch »

I ran the test.
I'm on linux using gcc and g++ and I get almost no difference
c 6.5 kb
c++ 7.9 kb

And I'm using iostream not cstdio with no optimizations .

maybe it's the compiler?
from Bjarne Stroustrup
Why is the code generated for the "Hello world" program ten times larger for C++ than for C?
It isn't on my machine, and it shouldn't be on yours. I have even seen the C++ version of the "hello world" program smaller than the C version. When I recently (2004) tested using gcc -o2 on a Unix, the two versions (iostreams and stdio) yielded identical sizes. There is no language reason why the one version should be larger than the other. It is all an issue on how the implementor organized the libraries. If one version is significantly larger than the other, report the problem to the implementor of the larger.
Post Reply