I've heard that you should prefer writing internal include guards instead of external include guards. I have searched around the internet but haven't found an answer to it.
This is a snippet of the book C++ Coding Standards by Herb & Andrei that shows an "external include guard":
Avoid using the obsolete external include guards advocated in older
books:
#ifndef FOO_HJNCLUDED_ //NOT recommended
#include "foo.h"
#define FOO_HJNCLUDED_
#endif
Now, this leads to the question below:
Q:
What is an internal include guard and what is an external include guard? What's the difference between the two, and why is internal include guards preferred? I would like that the answer also provide an example.
Edit: I ended up answering my own question.
Here's something I've seen that probably explains the comment.
Here, foo.h is defining an "internal include guard" (shortened to simply "include guard" by most people since it's the traditional way of doing it).
// foo.h
#ifndef _FOO_H__
#define _FOO_H__
// ...
#endif // _FOO_H__
In contrast, bar.h is using foo.h's include guard outside of foo.h. We can nickname this as an "external include guard".
// bar.h
#ifndef _BAR_H__
#define _BAR_H__
#ifndef _FOO_H__
#include "foo.h"
#endif
// ...
#endif // _BAR_H__
One (very large) project I worked on claimed that this increased compiling speed, but the claim is dubious as this seems to me like a trivial compiler optimization and I haven't seen any metrics to prove the claim. However, we did notice it was annoying to read when including multiple header files.
After a good digging around, I can now answer my own question.
Internal Include Guard:
The common idiom putting "include guards" around the content of header files being included:
header.h
#ifndef HEADER_H
#define HEADER_H
// Contents of include file
#endif
Therefore, the content of the header will be processed once even though the header is #includeed multiple times. This is known as an "internal include guard" because the guard is entirely internal to the header file.
External Include Guard:
However, there could be an issue with the above method if the compiler takes a simple approach, opening the file multiple times to check for "internal include guards" which could cause increased compile time in large projects.
header2.h
#ifndef HEADER_H
#include "header.h"
#endif
// Rest of header file goes here
The line: #ifndef HEADER_H is still defined and checked internally in header.h. But by checking it externally the compiler might avoid having to open the file at all.
It is only suggested to check externally when a header file is included from other header files. The check is not necessary when included from a source file.
Conclusion:
Internal guard guarantees correctness
External guard may improve speed of compilation on some compilers
The cost involved is that of putting the check everywhere a header file is #included in another header file, and spelling the name of the guard symbol correctly. Therefore not preferred.
Related
I am refactoring some existing software and I regularly see this
#define XYZ
#include "stdafx.h"
where stdafx is the precompiled header file.
Q1. Can a knowledgeable person please confirm the following?
That (except perhaps for the file stdafx.cpp) the correct order is always
#include "stdafx.h"
#define XYZ
My reasoning is as follows. A define before the precompiled header can't affect the precompiled header even if 'used' inside the header, since the header is precompiled. The precompiled header will have used whatever the macro XYZ was set to when the initial compilation took place.
So
#define XYZ
#include "stdafx.h"
misleads a reader into thinking XYZ may have an influence on the contents of stdafx.h.
Q2. Whether the two are functionally equivalent and my refactoring is safe?
#include "stdafx.h"
#define XYZ
clearly defines XYZ whereas the alternative does not so clearly define it. (Using the precompiled header might well overwrite the definition with some compilers, for all I know.) Yet defining XYZ before including the precompiled header does seem to work, as it is present so often in the code I am refactoring.
Q3. Is the behaviour defined in a standard?
If I were the compiler writer, I would reject any #define prior to inclusion of a precompiled header! My VS2019 doesn't.
You state:
A define before the precompiled header can't affect the precompiled header even if 'used' inside the header, since the header is precompiled.
But from the Microsoft documentation Precompiled Header Files:
[#defines] Must be the same between the compilation that created the precompiled header and the current compilation. The state of defined constants is not checked, but unpredictable results can occur if your files depend on the values of the changed constants.
I'm building my own terminal app project in C++ and I'm asking myself if standard library has ifdef or ifndef preprocessors instructions. I want to know that because I need to create different header files which need some standard library headers such as "string" and some others, i don't want to include the same library 3 or more times because it makes the program heavier.
For example i wrote on my header files something like this to prevent the .h file to be included more than once:
#ifndef myheader_h
#define myheader_h
// my file code here
#endif
I tried compiling but the compiler say me nothing about errors or warnings.
I also tried to read the standard-library source code (https://en.cppreference.com/w/cpp/header) and I haven't found any preprocessor rule like ifdef or ifndef.
Should i include standard library headers like this?
#ifndef string_h
#define string_h
#include <string>
#endif
I hope my question isn't already asked because I haven't found it while searching it.
Updates
To some who said "you're not in the position where you need to worry about" and who said "it costs very little if it has proper include guards", I meant: program's heaviness is important, I want to make it slighter so I don't want to entirely include the same file multiple times. Have std lib files proper include guards? (my header files have them, didn't know std lib files)
There is no requirement for the standard header files to #define any specific pre-processor symbols to make sure they can be #included multiple times.
Having said that, any sane implementation would make sure that they can be #included multiple times without adversely affecting application code.
Turns out, that is a requirement by the standard for most headers (Thanks, #Rakete1111).
From the C++ standard
A translation unit may include library headers in any order ([lex]). Each may be included more than once, with no effect different from being included exactly once, except that the effect of including either <cassert> or <assert.h> depends each time on the lexically current definition of NDEBUG.
Not only that, they are very likely to be using the #pragma once directive. Hence, even if you use #include multiple times for the same header, they are going to be read only once.
In summary, don't worry about standard header files. If your header files are implemented correctly, your application would be just fine.
Those preprocessor directives you're talking about are called "header guards", and the standard library headers definitely have them (or some other mechanism that does the same thing) like all other proper header files. Including them multiple times shouldn't cause any problems, and you only need to worry about these when you're writing your own header files.
The "source code" that you're reading is just the documentation which says how the header files should work, but it doesn't provide the actual code. To see the code, you can look in the header files provided by your compiler. For example, the <iostream> header in Visual Studio has both #pragma once and header guards:
#pragma once
#ifndef _IOSTREAM_
#define _IOSTREAM_
//...
#endif /* _IOSTREAM_ */
The headers provided by the GCC compiler also has header guards:
#ifndef _GLIBCXX_IOSTREAM
#define _GLIBCXX_IOSTREAM 1
//...
#endif /* _GLIBCXX_IOSTREAM */
I'm asking myself [sic] if standard library has ifdef or ifndef preprocessors instructions
The standard doesn't specify whether there are ifdef-style header guards, although it does require that multiple inclusion is protected in some manner. I took a look at a random header of stdlibc++ standard library implementation. It does have header guards.
i don't want to include the same library 3 or more times because it makes the program heavier
Including a header file multiple times does not make a program "heavier".
Should i include standard library headers like this?
#ifndef string_h
#define string_h
#include <string>
#endif
That is not necessary, or particularly useful.
how to check if one header include another header in c++?
for example, When I want to know if the include , but the include two many headers and header include other headers.So I have to check the source code one by one, So is there any quick method to find if one include another?
You should use an include guard. This will ensure the compiler does not include the header contents more than once.
An example header file, MyClass.h, using a standard include guard:
// MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
// Your header contents goes here
#endif
This will ensure that the compiler only includes the header contents once.
Alternatively, you can use #pragma once.
An example header file, MyClass.h, using non-standard #pragma once:
// MyClass.h
#pragma once
// Your header contents goes here
Note that #pragma once is not standard, so it will make your code less portable. However, it does use less code, and can avoid name clashes.
If myheader.h has what we call an include guard, then it will usually #define a macro with a name like MYHEADER_H. So first check whether your header file has this kind of thing.
If it does, you can check at any point whether it has been included (up to that point), using the #ifdef and #ifndef directives.
in some cases, the header guard mentioned in other answers will not suffice (e.g. your file is used on multiple systems or is built against separate versions or libraries and the hguard is inconsistent). In those cases, you can:
look for another identifier which is #defined in that header
or simply replace your inclusion of that header with your own little wrapper header which has a #define which does not vary by platform/architecture, then replace your #includes with the wrapper header. To illustrate:
#ifndef MON_HGUARD_CXX_CSTDIO
#define MON_HGUARD_CXX_CSTDIO
// now replace the following #include with inclusion of this header
#include <cstdio>
#endif // MON_HGUARD_CXX_CSTDIO
In my current project. A lot of my .cpp and .h files have plenty of includes in them such as 6 or 7 of headers declared in the following manner.
#ifndef A_Header
#include "a.h"
#endif
#ifndef B_Header
#include "b.h"
#endif
I wanted to know would it make sense if I wrapped all of these headers (used in the project) in a single header and then declare that header in each source file as such
#ifndef Wrapper_Header
#include "wrapper.h" /*This would contain a collection of all headers*/
#endif
Any suggestions and drawbacks of this plan that I am not anticipating?
That's totally bizarre.
Every header should contain a header guard:
#ifndef THIS_HEADER
#define THIS_HEADER
/* contents of the header */
#endif
This goes inside the header, not in the including .cpp file. The compiler detects the header guard and avoids re-reading all the text when it's included again. This can save seconds of compilation time.
If your headers have that, then the guards in the .cpp file are extraneous and you should remove them. 6 or 7 headers isn't a lot, but that silly boilerplate does sure add up.
Never wrap your headers, always be explicit, make it clear what is included, and do not include what you do not need.
Potatoswatter is correct
But I like to add use "forward declaration".
I am sure you can google it.
how does header including in c++ work? I have the classes already implemented in .h file and when there is #include in two files, there's this error:
files.h:14:7: error: redefinition of ‘class abstract_file’
files.h:14:20: error: previous definition of ‘class abstract_file’`
multiple times for each class and enum.
Can anyone explain this?
Using include in C++ simply takes the file included and splats the contents into where it is included. To do this without worrying about multiple includes of the same file, you want to use header guards. Use this basic format for all header files:
#ifndef FILENAME_H
#define FILENAME_H
class foo (or whatever else is in the file!) {
...
};
#endif
You can only include a definition one time but headers can be included multiple times. To fix that, add:
#pragma once
to the top of each header file.
While #pragma once is relatively common, if you are using an older compiler it may not be supported. In that case, you need to fall back on manual include guards:
#ifndef MY_HEADER_H
#define MY_HEADER_H
...
#endif
(note that you need to replace MY_HEADER_H with a unique string for each header file)
header files usually define a unique symbol so that they are only included once.
e.g.
#ifndef _myheader_h
#define _myheader_h
// rest of header goes here
#endif
Some compilers support
#pragma once
See Pragma Once on wikipedia.
While many people have solved your error for you, it seems that nobody has answered your initial question:
how does header including in c++ work?
When the preprocessor finds an #include directive it replaces it by the entire content of the specified file.
You can read more on preprocessor directives at cplusplus.com.
Update: To illustrate this, you could try the following if you have gcc handy:
echo '#include <iostream>' > test.cxx
gcc -E test.cxx
You'll see the contrents of iostream whizz past your eyes as the preprocessed source code is sent to standard output.
What you can do is to guard your header from multiple inclusions:
#ifndef MY_HEADER__
#define MY_HEADER__
/* your stuff goes here! */
#endif
You can also use:
#pragma once
but it is not standard although it is supported by many compilers.
Use include guards in header files:
#ifndef FILES_H
#define FILES_H
struct foo {
int member;
};
#endif // FILES_H
This makes sure that your header will only get included once.
Another method is to use #pragma once in your header files, but it's not standard C. It's supported by Visual C, GCC and Clang though, so most likely it's ok to use.