views:

350

answers:

8

When my cpp file uses #include to add some header, does my final program's size gets bigger? Header aren't considered as compilation units, but the content of the header file is added to the actual source file by the preprocessor, so will the size of the output file (either exe or dll) will be affected by this?

Edit: I forgot to mention that the question is not about templates/inline functions. I meant what will happen if I place an #include to a header that doesn't have any implementation detail of functions. Thanks

A: 

Yes, because for example inline functions can be defined in header files, and the code of those inline functions will ofcourse be added to your program's code when you call those functions. Also template instantiations will be added to the code of your program.

Jesper
Please see my edit, thanks :)
A: 

And you can also define global variables in header files (although I wouldn't recommend it). If you do, you should surround them with #ifdef/#end blocks so that they don't get defined in more than one compilation unit (or the linker would complain). In any case, this would increase the program's size.

Bill Lee
+8  A: 

It depends on the contents, and how your compiler is implmented. It is quite possible that if you don't use anything in the header your compiler will be smart enough to not add any of it to your executable.

However, I wouldn't count on that. I know that back in the VC++ 6 days we discovered that meerly #including Windows.h added 64K to the excecutable for each source file that did it.

T.E.D.
I can easily see this increasing the size of the object files, but I have difficult believing it increases the size of the resulting executable. Anything you're not using shouldn't be in there, and the linker should combine all the references to the stuff you are using into one place, so there would be a constant cost for using the header for the entire program. The only exceptions are of course inline functions and templates, which won't be compiled if they're not used. I use VC6 daily and have never seen this.
rmeador
Each of the object files may have increassed. But the resulting application will not have changed size. The compiler has to put in each compilation unit the stuff it may need. The linker then strips out dumplicate symbols (such as multiple versions of list<int>).
Martin York
Any data declared static in a header will be instantiated in each object file. Perhaps that was the cause?
Clifford
+1  A: 

With modern compilers included files only affect the binaries size if they contain static data or if you use normal or inline function that are defined in them.

Georg Fritzsche
+1  A: 

You clarified that:

[The header has no] templates/inline functions... doesn't have any implementation detail of functions.

Generally speaking, no, adding a header file won't affect program size.

You could test this. Take a program that already builds, and check the executable size. Then go into each .cpp file and include a standard C or C++ header file that isn't actually needed in that file. Build the program and check the executable size again - it should be the same size as before.

By and large, the only things that affect executable size are those that cause the compiler to either generate different amounts of code, global/static variable initializations, or DLLs/shared library usages. And even then, if any such items aren't needed for the program to operate, most modern linkers will toss those things out.

So including header files that only contain things like function prototypes, class/struct definitions without inlines, and definitions of enums shouldn't change anything.

However, there are certainly exceptions. Here are a few.

One is if you have an unsophisticated linker. Then, if you add a header file that generates things the program doesn't actually need, and the linker doesn't toss them out, the executable size will bloat. (Some people deliberately build linkers this way because the link time can become insanely fast.)

Many times, adding a header file that adds or changes a preprocessor symbol definition will change what the compiler generates. For instance, assert.h (or cassert) defines the assert() macro. If you include a header file in a .c/.cpp file that changes the definition of the NDEBUG preprocessor symbol, it will change whether assert() usages generate any code, and thus change the executable size.

Also, adding a header file that changes compiler options will change the executable size. For instance, many compilers let you change the default "packing" of structs via something like a #pragma pack line. So if you add a header file that changes structure packing in a .c/.cpp file, the compiler will generate different code for dealing with structs, and hence change the executable size.

And as someone else pointed out, when you're dealing with Visual C++/Visual Studio, all bets are off. Microsoft has, shall we say, a unique perspective around their development tools which is not shared by people writing compiler systems on other platforms.

Bob Murphy
A: 

For headers that are entirely declarative (as they generally should be), no. However the pre-processor and compiler have to take time to parse the headers, so headers can increase compile time; especially large and deeply nested ones such as - which is why some compilers use 'precompiled headers'.

Even inline and template code does not increase code size directly. If the template is never instantiated or an inline function not called, the code will not be generated. However if it is called/instantiated, code size can grow rapidly. If the compiler actually inlines the code (a compiler is not obliged to do so, and most don't unless forced to), the code duplication may be significant. Even if it is not truly inlined by the compiler, it is still instantiated statically in every object module that references it - it takes a smart linker to remove duplicates, and that is not a given - if separate object files were compiled with different options, inline code from the same source may not generate identical code in each object file, so would not even be duplicated. In the case of templates, and separate instantiation will be created for each type in is invoked for.

Clifford
A: 

Remember, #define sentences can bloat the code at compile time into a huge, yet functional compiled file.

Rodrigo
It is not the definition that does that, it is the expansion. If the macros are not referenced they have no effect. So this is not a direct consequence of including the header.
Clifford
Of course, man. This is why I wrote "can".
Rodrigo
A: 

It's good practice to limit the #includes in a file to those that are necessary. Besides affecting the executable size, having extra #includes will cause a larger list of compile-time dependencies which will increase your build-time if you change a commonly #included header file.

daveg
Most linkers throw away unused functions, don't they?
csl
Yes, the linker will probably throw away unused functions, but the "make" equivalent will recompile more files due the the added dependencies. Some builds will take longer.If you include "foo.h" in "bar.cpp" (even though it's not used in bar.cpp) and subsequently make a change in foo.h, bar.cpp will be forced to recompile next time you build.Forward declarations are preferred over #include statements in header files for that same reason. If you are only using references or pointers to a type in a class header you don't need to include the entire .h for that type.
daveg