• Advertisement
Sign in to follow this  

Relying on #includes from headers

This topic is 1659 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Generally speaking it is important in C++ to ensure that all files are self-sufficient and idempotent with respect to their #includes. They should explicitly include what they need and not rely on other files having done so already.

 

There is however a case (and possible exception) to be made for when you have pairs of header and source files, such as foo.h and foo.cpp. Usually these headers define a class called 'Foo' and the source file is always going to include the header because it provides the definition while the header provides the declaration.

 

My question is, if the header #includes something (say <string>), should the source file have to re-include it too?

 

The two major opinions around the office are:

 

1) Yes - because ALL files should include everything they need, no exceptions.

2) No - because the two files are really two halves of one thing, if there is an include in the header we needn't repeat that in the source.

 

I am a bit of a hypocrite on the subject, I quite like opinion #2 but have generally only practiced #1.

 

What do you think?

Certainly it would be interesting to know if there was a genuinely convincing reason to go one way or the other?

Share this post


Link to post
Share on other sites
Advertisement

If i have some method that is using some object (like string), and if it is not "visible" in class declaration (header) i include it only in cpp,  otherwise i include it in header.

Sometimes when my cpp is too big, i partition it in multiple cpp file, so i can follow it easily.

Share this post


Link to post
Share on other sites

My own convention is to #include in the header if and only if the header requires it (e.g. the header needs stdlib.h for a size_t parameter) and in the source file otherwise, but never in both.

 

I mean that too if it is not clear what i have written in my previous post.

Share this post


Link to post
Share on other sites

I try to avoid includes as much as possible in the headers, but I don't duplicate includes in the source file either. If it's included in the matching header, good enough.

Share this post


Link to post
Share on other sites

As a style, always program to an interface.  

 

The header files for those interfaces absolutely should not include headers like <string>.  An interface does not require it.

Share this post


Link to post
Share on other sites

I try as much as possible to avoid #include's in the header file, not only as a stylistic choice but also as a practical one to cut down on build times and prevent a header file change from causing half the solution to be rebuilt. However if something absolutely must be included in my header, for matching file pairs I won't re-include the header's dependencies in the source file. For everything else, I always include whatever the source file depends on regardless of what other headers are included, and what their included files are. That way if code is refactored in the future you don't have new compile errors pop up out of nowhere.

 

Around the office we've been using unity builds for awhile now, and that's when you need to be especially vigilant. I often run across code that doesn't compile on its own because it depends on the unity build to merge source files together in some non-deterministic way, which changes whenever files are added or removed from the project. Personally I always do a Ctrl-F7 just to make sure I've included all required headers, even if it's not strictly required for a build to be successful.

Share this post


Link to post
Share on other sites

I'd say that I'm in the "avoid #includes in headers whenever possible in favour of forward declarations" camp. In fact, I try to avoid #includes in source files, too. If however some aspect of your interface requires something defined in another header to be included just to parse the declaration, then I'd put the requisite #include in the header declaring the interface. That way, you can be sure that if you're #including the interface, your source file is including everything it needs to use your interface.

Share this post


Link to post
Share on other sites

As a style, always program to an interface.  

 

The header files for those interfaces absolutely should not include headers like <string>.  An interface does not require it.

Sorry, I'm slightly confused here.

 

What if the interface takes a string as a parameter? Do you forward declare string? Can you even do that, given that string is a typedef for 

 basic_string<char, char_traits<char>, allocator<char> >

at least on msvc.

Share this post


Link to post
Share on other sites

As a style, always program to an interface.  

 

The header files for those interfaces absolutely should not include headers like <string>.  An interface does not require it.

 

Then how do you use std::string in your class declaration?

I don't think we should forward declare symbols in third party or even system libraries.

Share this post


Link to post
Share on other sites

To answer OP's question, here is how I do in my code,

1, For the declarations (such as classes) in my code, I forward declare them whenever possible, in the header. Of course the source file needs to include the corresponding header, that's fine.

2, For the declarations in third party and system library, I never forward declare them. If I do, I will get a lot of trouble if the library changes the name or namespace.

3, I always try to avoid #include in the header (my point #1), but if I can't avoid, just include it (my point 2), no problem.

Share this post


Link to post
Share on other sites

I do everything I can to stop includes in headers, and use forward declarations instead. But if I need the #include in the header, I won't put it in the source file, it already has it in the header so it doesn't need it. If you don't see the #include for whatever you're using, it most likely is in the header. I despise multiple includes when they're not needed, it's equivelant to the sound of Styrofoam rubbing against other Styrofoam to me. 

Share this post


Link to post
Share on other sites

When you include <string> in a header it's because it must be there, you have no option to forward declare.  Since you know that this header will be in the cpp there is no reason to reinclude it in the cpp file, its already part of the classes declaration.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement