which #include method is better....

Started by
12 comments, last by ToohrVyk 18 years, 8 months ago
Which method is better in terms of compile speed and .exe size:

//In my_utils.h

#include <vector>
#include <map>
#include <string>
//..etc...

//-----------------
//In my_class.h

#include "my_utils.h" //has everything even though it only needs a vector

class some_class
{
    std::vector <int> int_array;

public:
    //some member functions....
};


or...

//In my_class.h
#include <vector> //every file that needs a vector must include the file

class some_class
{
    std::vector <int> int_array;

public:
    //some member functions....
};


I've never been quite sure how the compiler puts together translation units especially ones containing templated code. Any thoughts? Thanks :)
Advertisement
The first method will be considerably faster to compile if you use precompiled headers correctly. The two versions should produce the same code.

Skizz
It's a matter of coupling and what you really want is to in headers include the bare minimum to make them compile as the only line in an implementation file.

That often means forward declaring classes only passed and returned as pointers or references.

This is a good thing since it physicly decouples your project proventing a small change to erupt into a nasty recompile of the whole codebase.

Sure it will require some extra typing on your part but in the long run you'll have a much healtiher codebase from it.

Oh, and about speed, modern compilers are smart enough to not reread headers included multiple times rendering use of "hacks" like #pragma once needless to.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
Quote:Original post by DigitalDelusion
Oh, and about speed, modern compilers are smart enough to not reread headers included multiple times rendering use of "hacks" like #pragma once needless to.


Is this really a good thing? Consider the following situation:

// foo.h#ifndef ONCEint foo(int bar) { return bar; }#define ONCE#else#ifndef TWICE#define TWICEint foo(float bar) { return bar * 2.0f; }#endif#endif//foo.c#include <iostream>#include "foo.h"#include "foo.h"int main() {  std::cout << foo(1.0f) << std::endl;  return 0;}


A "smart" compiler that ignores duplicate includes will display "1", a standards-respecting compiler would display "2.00000".
Quote:Original post by DigitalDelusion
Oh, and about speed, modern compilers are smart enough to not reread headers included multiple times rendering use of "hacks" like #pragma once needless to.


That would actually be very, very stupid of a compiler.
Try this:
//Test.h#ifdef MYDEFINEvoid DoSomething(){}#elsevoid DoSomethingElse(){}#endif//main.h#include "Test.h"#define MYDEFINE#include "Test.h"int main(){ DoSomething(); DoSomethingElse();}


Notice that the two places I include will produce different code. Why would I want to do this? Check out boost::preprocessor for using this multiple including of the same file to great effect.

You can also try including a file twice in your favorite compiler and observe the errors that occur.

Edit: Seems ToohrVyk and I were thinking the same thing, I just took longer to type the message. ;)
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
#pragma once is a ugly hack, proper use of inclusion guards are not.

Im fully aware that you can want diffrent things from the same file (X macros comes to mind) and maybe I should have been explicit about the compiler not reread the file.

It has been benchmarked in various sources that using "#pragma once" doesn't provide any benefit at all over using normal inclusion guards, and that there very seldom is any benefit in using external guards.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
Wow fast replies!! [smile]

So as I understand it the first method will reduce compile time whilst the second method would reduce the size of the executable?

Since the STL headers contain template code does that mean they are compiled differently - i.e. only compiled when actually used.
Quote:Original post by ToohrVyk
Quote:Original post by DigitalDelusion
Oh, and about speed, modern compilers are smart enough to not reread headers included multiple times rendering use of "hacks" like #pragma once needless to.


Is this really a good thing? Consider the following situation:

*** Source Snippet Removed ***

A "smart" compiler that ignores duplicate includes will display "1", a standards-respecting compiler would display "2.00000".


A "smart" compiler should complain of multiple function declarations, so a standards compiler would not display 2, it wouldn't display anything but an error ;).
Quote:Original post by dmatter
Wow fast replies!! [smile]

So as I understand it the first method will reduce compile time whilst the second method would reduce the size of the executable?

Since the STL headers contain template code does that mean they are compiled differently - i.e. only compiled when actually used.


The linker will happily flush them out anyhow so exe size till be constant. It's the same as with unused functions even if they do end up in our object files the linker happily removes them later if they're never referenced.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
Quote:Original post by dmatter
Wow fast replies!! [smile]

So as I understand it the first method will reduce compile time whilst the second method would reduce the size of the executable?

Since the STL headers contain template code does that mean they are compiled differently - i.e. only compiled when actually used.


Truly, the benifit to the second method, that is including only what the header file itself needs in the header and including what the source file needs in the source file, is that you can quickly yank the header and source from one project and dump it into another, without having to edit the files. It also provides faster minimal-rebuilds, because changing one header only causes recompilation of files actually affected rather than pretty much all files (proper use of precompile headers probably prevents this, I don't know, I use the minimal inclusion method primarilly for the first reason I list).
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?

This topic is closed to new replies.

Advertisement