I just found that this particular compiler adds 123 to 124 kilobytes of code for operator new on trivial types, any idea how and why?
The verdict is this:
I started writing a parser, and relatively early (when the compiled code size was around 10kB) I added a std::vector in some place. Nothing fancy, and 3-4 harmless lines of code. Bang. Executable size jumped well above 134kB. I noticed by accident because Code::Blocks displays the size in the log pane.
Not like 134kB is a forbiding size on a modern computer, but... wow, dude, std::vector seems to be quite a fat pig, seeing how it's supposed to be kinda slim wrapper around an array with some rather simple resizing logic. Probably a lot of debug symbols and stuff... hmm... no, already building without symbols, optimizing, and stripping. Huh. It's not symbols, then it must be RTTI and exceptions. The code doesn't use these, but std::vector throws, so that's probably it. Building with exceptions and RTTI disabled. Same thing.
If I comment out the single push_back, code size drops back to 10kB. What the hell is push_back doing that's so complicated?
Well, it seems std::vector just sucks, so I'll just write my own implementation, and one that doesn't need to be 100% standards compliant, too (so I can cut a few corners). Fast forward one day. Well, it works fine, but it's exactly the same code size, WTF? Dude, WTF? I know that my code doesn't do anything that justifies this bloat. How is this possible?
Commenting out line by line to find the culprit. When commenting out the new expression inside the reallocation function, code size suddenly drops to 9.5kB.
Uh huh. So... let's try something different. Ignoring the correctness issues of leaking and returning an undefined value, let's check the difference between these three:
int main() { }
int main() { return *(int*)malloc(4); }
int main() { return *new int; }
9kB / 9kB / 134kB. How is that possible? Trying Clang/LLVM 3.7: 15.5kB / 15.5kB / 15.5kB. Trying MinGW-w64 (the 5.1 and 5.2 versions available from the MinGW-w64 site): 9kB / 9kB / 9kB.
Running objdump -dSC and diffing the outputs unsurprisingly shows generally similar code at the beginning (with different addresses in JMP/CALL, but otherwise identical) followed by loads of extra code. It's most definitively not symbols or something the like.
Any idea what I'm doing wrong?