13

My executable was 364KB in size. It did not use a Vector2D class so I implemented one with overloaded operators.

I changed most of my code from

point.x = point2.x;
point.y = point2.y;

to

point = point2;

This resulted in removing nearly 1/3 of my lines of code and yet my exe is still 364KB. What exactly causes it to grow in size?

Anthony
  • 12,177
  • 9
  • 69
  • 105
jmasterx
  • 52,639
  • 96
  • 311
  • 557
  • 1
    Why would it be less? `point = point2` is doing the exact same work as before (inside the operator), just with a different interface. – GManNickG Aug 19 '10 at 23:55
  • 1
    @GMan: that's why he's asking this question...perhaps he believes that the exe's grew in size based on the lines of code. – Jorge Israel Peña Aug 19 '10 at 23:57
  • 4
    Im going to upvote this simply for the fact that this is a really good question that a lot of people ask when their starting programming. – Faisal Abid Aug 20 '10 at 00:03
  • 1
    I'm slightly at a loss where the "grow in size" title is coming from. The actual question wonders why the executable stays the same size. The discrepancy seems to have caused a few unjustified downvotes. – MSalters Aug 20 '10 at 07:25

8 Answers8

11

The compiler probably optimised your operator overload by inlining it. So it effectively compiles to the same code as your original example would. So you may have cut down a lot of lines of code by overloading the assignment operator, but when the compiler inlines, it takes the contents of your assignment operator and sticks it inline at the calling point.

Inlining is one of the ways an executable can grow in size. It's not the only way, as you can see in other answers.

Anthony
  • 12,177
  • 9
  • 69
  • 105
  • "Why?" Because your answer doesn't address the "What makes EXE’s grow in size?" part. – SigTerm Aug 20 '10 at 01:12
  • downvoted, because not all people here are very bright. I think it's an excellent answer btw. upvote for me. – C.J. Aug 20 '10 at 02:25
9

What makes EXE’s grow in size?

External libraries, especially static libraries and debugging information, total size of your code, runtime library. More code, more libraries == larger exe.

To reduce size of exe, you need to process exe with gnu strip utility, get rid of all static libraries, get rid of C/C++ runtime libraries, disable all runtime checks and turn on compiler size optimizations. Working without CRT is a pain, but it is possible. Also there is a wcrt (alternative C runtime) library created for making small applications (by the way, it hasn't been updated/maintained during last 5 years).

The smallest exe that I was able create with msvc compiler is somewhere around 16 kilobytes. This was a windows application that displayed single window and required msvcrt.dll to run. I've modified it a bit, and turned it into practical joke that wipes out picture on monitor.

For impressive exe size reduction techniques, you may want to look at .kkrieger. It is a 3D first person shooter, 96 kilobytes total. The game has a large and detailed level, supports shaders, real-time shadows, etc. I.e. comparable with Saurbraten (see screenshots). The smallest working windows application (3d demo with music) I ever encountered was 4 kilobytes big, and used compression techniques and (probably) undocumented features (i.e. the fact that *.com executbale could unpack and launch win32 exe on windows xp)..

In most cases, size of *.exe shouldn't really bother you (I haven't seen a diskette for a few years), as long as it is reasonable (below 100 megabytes). For example of "unreasonable" file size see debug build of Qt 4 for mingw.

This resulted in removing nearly 1/3 of my lines of code and yet my exe is still 364KB.

Most likely it is caused by external libraries used by compiler, runtime checks, etc. Also, this is an assignment operation. If you aren't using custom types for x (with copy constructor), "copy" operation is very likely to result in small number of operations - i.e. removing 1/3 of lines doesn't guarantee that your code will be 1/3 shorter.

If you want to see how much impact your modification made, you could "ask" compiler to produce asm listing for both versions of the program then compare results (manually or with diff). Or you could disasm/compare both versions of executable. BUt I'm certain that using GNU strip or removing extra libraries will have more effect than removing assignment operators.

SigTerm
  • 26,089
  • 6
  • 66
  • 115
6

What type is point? If it's two floats, then the compiler will implicitly do a member-by-member copy, which is the same thing you did before.

EDIT: Apparently some people in today's crowd didn't understand this answer and compensated by downvoting. So let me elaborate:

Lines of code have NO relation to the executable size. The source code tells the compiler what assembly line to create. One line of code can cause hundreds if not thousands of assembly instructions. This is particularly true in C++, where one line can cause implicit object construction, destruction, copying, etc.

In this particular case, I suppose that "point" is a class with two floats, so using the assignment operator will perform a member-by-member copy, i.e. it takes every member individually and copies it. Which is exactly the same thing he did before, except that now it's done implicitly. The resulting assembly (and thus executable size) is the same.

EboMike
  • 76,846
  • 14
  • 164
  • 167
  • Who's voting down without a comment? What's up with that? – EboMike Aug 20 '10 at 01:19
  • It answered the question exactly. Maybe you didn't understand my answer? Assuming (based on the limited information in the question) that his "point" is a class that contains two floats, then using the assignment operator will do a member-by-member copy, i.e. it will copy both floats individually. Which is the exact same thing as he did before. Bottom line - different source code, identical assembly code. There, how did that not answer the question? – EboMike Aug 20 '10 at 02:12
  • @EboMike: Your edit answers the question, initial answer didn't. +1 Your initial answer was more like a comment than an answer. I only downvoted once, apparently someone else felt the same way. –  Aug 20 '10 at 13:01
  • @0A0D: The initial answer still explained the question, i.e. why the shorter code created the same executable as the longer one. Anyway. (The other downvote was presumably SigTerm, who seems to have gone through every other answer here and downvoted it without comment.) – EboMike Aug 20 '10 at 15:15
4

Executables are most often sized in 'pages' rather than discrete bytes.

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
  • "would the downvoter" Same thing. The answer doesn't address "what makes exe grow in size". Pages or not, it is normally possible to reduce size of 300+ kb executable. – SigTerm Aug 20 '10 at 02:01
  • It does answer the question: removing a few lines of code may not be enough to shrink below the next lower page size. – Mitch Wheat Aug 20 '10 at 03:01
3

I think this a good example why one shouldn't worry too much about code being too verbose if you have a good optimizing compiler. Instead always code clearly so that fellow programmers can read your code and leave the optimization to the compiler.

AndersK
  • 35,813
  • 6
  • 60
  • 86
2

Some links to look into

http://www2.research.att.com/~bs/bs_faq.html#Hello-world

GCC C++ "Hello World" program -> .exe is 500kb big when compiled on Windows. How can I reduce its size?

http://www.catch22.net/tuts/minexe

As for Windows, lots of compiler options in VC++ may be activated like RTTI, exception handling, buffer checking, etc. that may add more behind the scenes to the overall size.

Community
  • 1
  • 1
David
  • 3,324
  • 2
  • 27
  • 31
1

When you compile a c or c++ program into an executable, the compiler translates your code into machine code, and applying optimizations as it sees fit. But simply, more code = more machine code to generate = more size to the executable.

firas
  • 1,463
  • 4
  • 19
  • 42
0

Also, check if you have lot of static/global objects. This substantially increase your exe size if they are not zero initialized.

For example:

int temp[100] = {0};
int main()
{

}

size of the above program is 9140 bytes on my linux machine.

if I initialize temp array to 5, then the size will shoot up by around 400 bytes. The size of the below program on my linux machine is 9588.

int temp[100] = {5};
int main()
{

}

This is because, zero initialized global objects go into .bss segment, which ill be initialized at once during program startup. Where as non zero initialized objects contents will be embedded in the exe itself.

chappar
  • 7,275
  • 12
  • 44
  • 57