The role of a header file in compilation? - c++

We have been asked a question in a practice paper 'What is the role of the header file in compilation? What are header guards used for in this context?'
A header file will have any declarations for classes which may be included in .cpp implementations. I understand that by including a header file in an implementation or other header file, it is possible for that code to know all the possible members of the class without knowing its implementation.
Having done a little reading through StackOverflow, some have suggested that header files can possibly slow down compilation (Coding C++ (mostly) in header files vs .cpp files) and that while a change to a header file will require a full rebuild of all implementations, while a change to an implementation does not require a full rebuild of the header file and all its implementations.
Would these be accurate? Is there any reason that a header file is necessary of beneficial in compilation and what role does it play?
Many thanks!

yes, although I would avoid using the term implementations for code files - people may think you are talking about the implementation of the class(es) in the headers, which could lead to confusion.
Also, changing a header file will not result in you needing to rebuild all the code files - only those which include (directly or otherwise) said header file.
Oh, and header guards are used to avoid the same file being included twice in a given compilation unit (resulting in redefinitions of things).

Related

C++ Header and Source file design implementation

I have a few queries regarding the design principle of laying out a C++ header and source files:
I have recently taken over a project in which the previous programmer used to have this, which is particularly annoying because I read somewhere that we shouldn't include a .cpp file in a .hpp file (The preprocessor will just copies and pastes the .cpp file into a .hpp)
Q1. Including a .cpp file in a .hpp file is bad? why?
Due to the problem above, I am facing many "multiple declaration" errors when I load my program in eclipse, even though i added the header guards in all the .hpp files.
Q2. Should i be including the header guards in the .cpp files as well?
I tried the later too but to no avail. Any suggestions on this?
Q3. If 2 or more of my .cpp files need the same header files to be
used what is the best way to include all those header files? Should i
create a new header file say h1.hpp, include all the header files I
need in those 2 or more .cpp files and later include in this header
file in those .cpp files(s)?
Is it an efficient approach ?
Including a .cpp file in a .hpp file is bad? why?
In a typical code setup, yes. It serves no useful purpose and can lead to "duplicate definition" errors.
More importantly, it mixes the separation between the implementation and interface parts. When a file containing implementation is meant to be included, it's often changed to .inl (from "inline") extension.
Should i be including the header guards in the .cpp files as well?
No. Header guards prevent two (or more) other headers in one translation unit from including the same header twice. Since there's only one .cpp file per translation unit, this problem doesn't occur there.
To illustrate, an example inclusion could look like this:
common.hpp
/ \
/ \
A.hpp B.hpp
\ /
\ /
file.cpp
In this case, header guard in common.hpp prevents it from appearing twice in the TU introduced for file.cpp.
If 2 or more of my .cpp files need the same header files to be used what is the best way to include all those header files?
You shouldn't be scared by a long include chain, in general. It's less scary than it looks. That being said, "aggregate" headers can be used if the headers actually form a tree structure (to make including subsets easier, like collections.hpp and collections/vector.hpp + collections/list.hpp) or to include every header from the library.

C++ Struct prototyping in separate header file

I am having trouble understanding an answer I saw in another post. It said that it is good practice to define a struct in a separate .h file so it can be used in other files. I think that is great and it solves my current dilemma, however I have a question about compilation and makefiles. I am only familiar with having header files that are associated with .cpp files at the moment.
Can someone explain how that implementation would look when I have a .h and no .cpp? Do I need an implementation file as well? Also, how do I link the header in a makefile? Currently I only know how to compile a .cpp & header into a .o file and link them.
Thanks, and sorry for taking us back to c++ kindergarten. This is a new revelation and seems like a good one.
You don't need a matching source file (.c or .cpp) for every header .h file.
Having header files without corresponding source files is just fine.
When you #include some header file, you can think of it as a kind of "copy and paste" operation: the preprocessor copies the content of the header file, and pastes it in the point of inclusion.
(Well, there are some details to consider here, for example the presence of a #pragma once directive or some #ifdef inclusion guard can prevent multiple inclusions of the same header file in a given project.)
The C and C++ compilers will then process the whole "compilation unit", i.e. the current source file with all the included headers.
The key concept is that you define the struct/class in a .h header, so that you can use it in multiple .cpp files. Whenever you need struct foo defined in foo.h, you #include "foo.h". You don't need to directly compile the header file, it will be pulled in by whichever source file uses it. Therefore you don't need a make target for .h in normal circumstances.
If the definition in the header is never used, it won't be pulled in and that's it.

c++ when to include cpp even if we have .h file

I am reading the book Absolute C++ 5th edition.
In page 716,
I don't really understand why it needs include "pfarray.cpp"
Is include "pfarray.h" not enough?
More specifically, even if we have declarations in .h file but implementations in .cpp files, when we still have to include .cpp file?
Thank you in advance.
You don't have to.
A translation unit is a group of files with definitions and declarations. Compiling a translation unit, the compiler needs to know everything about declarations and re-parse them again and again. The definitions on the other hand can be compiled just once and reused for another units.
A translation unit can be separated in .h and .cpp files. You should put the declarations in .h and definitions in .cpp files to obey one definition rule. This approach also reduces compilation time.
Writing template-d classes and functions (without specialization), some coders (a bad habit in my opinion) will put the implementations in the .cpp files and they have to include them at the end of its corresponding .h file or in a .cpp file which needs them. It's just confusing. A better naming convention is to rename these type of .cpp files to .impl.cpp and including them at the end of its .h file.
When you write #include anything.any_extension, the extension doesn't really matter to the preprocessor. It's really like a "take the contents from that file and paste it into this file" kind of brute mechanism. So you can include anything without error provided that the code inside is legit, and you can name a header file with any extension. So you can even name them with a .txt extension and it wouldn't really matter to the preprocessor.
I would suggest that the practice of including source files is rather confusing, mainly from a build standpoint since it's not very clear whether a source file (cpp, cc, etc) is supposed to be built as a separate object file to link against or #included or both.
Yet it's sometimes done anyways. For example, pfarray.cpp might contain an implementation for a template since templates typically need their full implementation visible at compile time at the site generating the code, and sometimes authors establish a habit of #including files with source file extensions to avoid putting the implementation details into the same header file while uniformly conforming to a style that favors putting all such details into files named with a source file convention.
Another reason this can be done, but I don't think it's the reason it was done in your case, is as a build optimization (see Unity builds). It can sometimes be more efficient to compile and link fewer files, so using #include for source files can be a crude way to fuse them all together into a single build target.

Headers without cpp files and include ordering

There was a highly rated response in a question about header ordering with the following suggestion:
Good practice: every .h file should have a .cpp that includes that .h first before anything else. This proves that any .h file can be put first.
Even if the header requires no implementation, you make a .cpp that just includes that .h file and nothing else.
Personally I've never had a problem with include ordering for headers that don't have a corresponding cpp file. What kinds of problems does this best practice prevent?
The header file should compile on itself. ie. for testing make a .cpp file that just includes the header file.
The header file should be guarded by the pre-processor. if #ifndef etc...
Both these will ensure that the order will not matter.
One problem it solves is allowing the .h file to be linted (at least by my lint tools). Without a .cpp doing an include of an .h my template code gets skipped.

Does it matter whether I put an #include directive in my cpp file or in an included header file?

My c++ program is using a separate header file (Let's call it myHeader.h) and therefore includes it (#include "myHeader.h"). In my program I need to use another header file (Let's call it another.h). Does it make a difference whether I put the #include "another.h" directive in the cpp file or in myHeader.h?
If it's not used in the .h file, then there will be no difference in compilation success/failure.
However, it is recommended to put include for header files you only need in the implementation in the .cpp files for the following reasons:
for encapsulation reasons - no one needs to know what you include solely for the implementation.
Including a file A.h in a header file B.h will also make any file that includes B.h include A.h. That can cause major dependency issues between seemingly unrelated files.
for the above reason, it can also increase build time substantially (every file you include is copied in your compilation unit).
If you need to include a header only in your cpp file then you should include it in your cpp file.
If you include it in your header it will add unneeded dependencies for everyone else who includes your header. This can explode if the unneeded headers you include also include other unneeded headers of their own.
The answer to your question is "No". However, you should try to avoid making unnecessary include statements in your .h files because it will induce longer build times. It is also better for encapsulation reasons as well.
Assuming all your include guards are in place etc then no.
It's best to think of how the user will use the code and try and avoid surprises for them.
In general you should avoid complex trees of include files included form other include files - although precompiled headers on modern compilers help.
BUT you should also make sure that you have all the advanced declarations in place so that the order of includes in a cpp file doesn't matter.
No difference really. Header files and cpp files can both include other files. The included files are effectively copied into the text stream.
There is a difference - every time your h file is included, any files included in that h file are included as well - I haven't kept up-to-date with modern C++ compilers, but this used to really increase compile time.
It also increases the physical dependency of the source - John Lakos' Large Scale C++ Software Design addresses this, and is well worth a read on structuring c++ programs. It's published in 1996, so it's not based around current practice, but the advise on structure is worth knowing.