I was once told in a programming class that C++ had achieved a better readability by letting the programmer declare its variable anywhere in a function block. This way, the variables were grouped together with the section of the code that dealt with it.
Why don’t we do the same for includes?
Put differently, why is it discouraged to put the include file next to the definition that will actually use it?
parser::parser()
{
// some initialization goes there which does not make use of regex
}
#include <boost/regex.hpp>
parser::start()
{
// here we need to use boost regex to parse the document
}
One of the reasons for this is that
#includeare context-less, they are just plain text inclusion, and having it in the middle of the code might have some unwanted effects. Consider for example that you had a namespace, and all your code in this file belongs to the namespace:Now that might even compile fine… and wrong. because the inclusion is inside a namespace, the contents of the file are dumped inside
nsand the included file declares/defines::ns::std::vector. Because it is header only it might even compile fine, only to fail when you try to use that in an interface with a different subsystem (in a different namespace) — This can be fixed, you only need to close all contexts, add the inclusion and reopen the same contexts…There are other situations where the code in your translation unit might actually affect the includes. Consider, for example, that you added a
using namespacedirective in your translation unit. Any header included after that will have theusing namespacedirective in place, and that might also produce unwanted effects.It could also be more error prone in different ways. Consider two headers that defined different overloads of
fforintanddouble. You might add one (say theintversion) towards the beginning of the file and use it, then add the other and use it. Now if you callf(5.0)above the line where the second header is included, theintversion will be called –only overload available to the compiler at this point–, which would be a hard to catch error. The exact same line of code would have completely different meaning in different places in your file (admittedly that is already the case, but within the declarations in your file it is easier to find which is the one being picked up and why)In general, the includes declare elements that you will be using in your component, and having them on the top provides a list of dependencies in a quick glance.