Lets say I am using header guards,
#ifndef MAIN_H
#define MAIN_H
#include "foo.h"
#include "some_header_file.h"
... // Some Code
#endif
Inside foo.h file also with Header guards.
#ifndef FOO_H
#define FOO_H
#include "some_header_file.h"
... // Some Code
#endif
As you can see main file have 2 headers one of them is dublicate. I have three questions:
Does Header guards prevent duplicate header files?
Does the compiler optimize it and removes it?
Is this a bad practice and the extra header file should be deleted from main file?
Does Header guards prevent duplicate header files?
Yes. The first encountered inclusion will bring the content of the header to the translation unit, and the header guard causes successive inclusions to be empty which prevents the content of the header from being duplicated. This is exactly the reason why header guards are used.
or is this a bad practice and the extra header file should be deleted from main file?
No, the duplicate inclusion is not a bad practice. If the "main" header depends on any declaration from "some_header_file.h", then "main" absolutely should include "some_header_file.h" directly, whether another header - even one included by "main" - also includes it or not.
Relying on a transitive inclusion would generally be a bad practice - i.e. in this case it may be bad to rely on the detail that "foo.h" includes "some_header_file.h" when including "foo.h" into "main". Such assumptions often can cause programs to break unexpectedly when they are modified. In this case, if "foo.h" was modified to no longer depend on "some_header_file.h", and that inclusion was removed, then that change would suddenly cause the assumption to fail, and "some_header_file.h" would no longer be included into "main" as a result of change that didn't involve "main" at all. That would be bad.
The main problem with repited includes is when two different files include each other. For example, if a.h include b.h, and b.h includes a.h, if you don't add header guards, preprocessor ends up in a cycle, because every time it reads a.h includes b.h, and b.h includes a.h, and this never ends.
In your case you could have some problem if you define a variable in your some_header_file.h", because it would be read twice and the variables would be declared twice also, which would result in a compiler error.
You need to add them in "some_header_file.h", that way next time preprocessor reads this file it would ignore it by the ifndef clause. And notice the importance for cyclic include dependencies.
In "some_header_file.h" add:
#ifndef SOME_HEADER_FILE_H
#define SOME_HEADER_FILE_H
...code
#endif /* SOME_HEADER_FILE_H */
Last comment isn't necessary, but it helps case you need to debug/review preprocessors output.
Related
As I understand, when compiling a compilation unit, the compiler's preprocessor translates #include directives by expanding the contents of the header file1 specified between the < and > (or ") tokens into the current compilation unit.
It is also my understanding, that most compilers support the #pragma once directive guarding against multiply defined symbols as a result of multiple inclusion of the same header. The same effect can be produced by following the include guard idiom.
My question is two-fold:
Is it legal for a compiler to completely ignore an #include directive if it has previously encountered a #pragma once directive or include guard pattern in this header?
Specifically with Microsoft' compiler is there any difference in this regard whether a header contains a #pragma once directive or an include guard pattern? The documentation suggests that they are handled the same, though some user feels very strongly that I am wrong, so I am confused and want clarification.
1 I'm glossing over the fact, that headers need not necessarily be files altogether.
It the compiled program cannot tell whether the compiler has ignored a header file or not, it is legal under the as-if rule to either ignore or not ignore it.
If ignoring a file results in a program that has observable behaviour different from a program produced by processing all files normally, or ignoring a file results in an invalid program whereas processing it normally does not, then it is not legal to ignore such file. Doing so is a compiler bug.
Compiler writers seem to be confident that ignoring a once-seen file that has proper include guards in place can have no effect on the resulting program, otherwise compilers would not be doing this optimisation. It is possible that they are all wrong though, and there is a counterexample that no one has found to date. It is also possible that non-existence of such counterexample is a theorem that no one has bothered to prove, as it seems intuitively obvious.
I think you can treat #pragma once as compiler language extension like for instance #pragma omp parallel that can make a loop execute in parallel causing all kinds of UB if it is not written correctly.
The standard says it is ok for pragma directive to cause implementation-defined non-conforming result:
Pragma directive [cpp.pragma]
...
causes the implementation to behave in an implementation-defined manner. The behavior might cause
translation to fail or cause the translator or the resulting program to behave in a non-conforming manner.
Any pragma that is not recognized by the implementation is ignored.
Regarding MSVC behavior you can think of it skipping the header based on its normalized path.For instance you can trick the compiler with symlinks:
test/test.h
#pragma once
static int x = 2;
Create symlink "test-link" to "test" directory:
mklink /d test-link test
Then in main.cpp:
#include "test/test.h"
#include "test/test.h"
#include "test/../test/test.h"
is ok. but
#include "test/test.h"
#include "test-link/test.h"
causes
error C2374: 'x': redefinition; multiple initialization
which would not happen in case of include guards.
Is it legal for a compiler to completely ignore an #include directive if it has previously encountered a #pragma once directive or include guard pattern in this header?
That depends on how #pramga once is defined and implemented by the compilers. It is after all a none standard feature.
But, all compilers I know that support #pramga once treat it like a non-mutable unique include guard that wraps around the complete file.
After the preprocessor resolved the include path for an include, it can check if that file was already included and if #pargma once exists for that file. If both conditions are true, it is safe to not include the file anymore, because it would follow the as-if rule, as the compiler vendor is in full controller over how the #pramga once is implemented and can ensure that the lock guard is unique, non-mutable, and wraps the whole file, and due to that a repeated inclusion of that same wile would result in an empty content that is included.
So with that respect, if they didn't make an implementation error it is safe to then ignore the include.
There is the argument against the usage of #pragma once that says that the compiler might treat the same file as different files due to symlinks and hard links. That would result in accidentally including the same file multiple times, but that won't affect the part of whether it is safe to ignore it if the compile identified it as the same file.
Specifically with Microsoft' compiler is there any difference in this regard whether a header contains a #pragma once directive or an include guard pattern? The documentation suggests that they are handled the same, though some user feels very strongly that I am wrong, so I am confused and want clarification.
If no #pragma once is used it becomes more complicated. The preprocessor needs to first check if the lock guard wraps around all contents:
#ifndef SOME_GUARD_NAME_H
#define SOME_GUARD_NAME_H
// all content of the file
#endif
Or if it is something like this:
// some content before the guard
#ifndef SOME_GUARD_NAME_H
#define SOME_GUARD_NAME_H
// some content
#else
// some more content
#endif
// some other content after the guard
And it needs to keep track of whether the SOME_GUARD_NAME_H was already defined in another file or if #undef was called by another file.
So in that case it can only ignore the content of the file if it can ensure that all relevant defines are the same and/or if the evaluation of the macros results in an empty file.
Is it legal for a compiler to completely ignore an #include directive if it has previously encountered a #pragma once directive or include guard pattern in this header?
Of course it is! It is even legal for the compiler to ignore all your source files and header files so long as behavior of the generated code is the same as if it processed everything. That's how pre-compiled headers and object files work - anything that hasn't changed can be safely ignored. Similarly, if the compiler can prove that including and not including the file are going to have exactly the same behavior, the compiler may ignore the file, regardless of the pre-processor directives.
Specifically with Microsoft' compiler is there any difference in this regard whether a header contains a #pragma once directive or an include guard pattern?
The documentation is pretty clear on that. They are identical assuming the compiler manages to identify the idiom and you haven't #undefed the macro. I've never experienced any bugs related to that either. #pragma once is safer though. I have had an instance where two headers had the same include guard and debugging that wasn't a nice experience.
#pragma once obviously refers to the file as a whole
The use of #pragma once can reduce build times, as the compiler won't
open and read the file again after the first #include of the file in
the translation unit.
really - if not to file - for what it can be related ?
the conditional compilation , so called guard idiom related not to file but to block of code. really - where, how stated that some condition related to file ?!
it related to block beginning with #if* and ended with #endif. compiler anyway need include this file again.
let do some tests. also here will be very useful cl(msvc) compiler option /showIncludes
let create header.h
// header.h
#ifndef HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
and then
#include "header.h"
#include "header.h"
only once in log
1>Note: including file: .\header.h
so header.h really included only once here.
but if do this
// header.h
#if !defined HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
or this
#if !defined(HEADER_H_)
#define HEADER_H_
int g_a = 0;
#endif
and
#include "header.h"
#include "header.h"
already 2 lines in log - header.h included 2 time.
1>Note: including file: .\header.h
1>Note: including file: .\header.h
so #ifndef HEADER_H_ have different effect compare #if !defined(HEADER_H_)
or if do
// header.h
#ifndef HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
#define XYZ
or
// header.h
#if __LINE__ // any not empty statement
#endif
#ifndef HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
and
#include "header.h"
#include "header.h"
already
1>Note: including file: .\header.h
1>Note: including file: .\header.h
again 2 lines in log - header.h included 2 time.
so if exist any not empty ( comments, sequences of whitespace characters (space, tab, new-line)) statement outside first conditional block - file already included more times.
of course possible and do next
// header.h
#include "header.h"
#undef HEADER_H_
#include "header.h"
in this case
1>Note: including file: .\header.h
1>Note: including file: .\header.h
1>.\header.h(4): error C2374: 'g_a': redefinition; multiple initialization
1>.\header.h(4): note: see declaration of g_a'
and of course in case
// header.h
#pragma once
int g_b = 0;
and
#include "header.h"
#include "header.h"
only single line
1>Note: including file: .\header.h
so based on tests can make next conclusion - if cl(msvc) - view that file have pattern
#ifndef macro // but not #if !defined macro
#define macro
// all code only here
#endif
macro associates with the file and then as long as it is not undefined - the file will not be included more. this is implicit optimization by specific compiler. and very fragile. any not white space or comment statement break it. even despite documented that #ifndef HEADER_H_ quivalently to #if !defined HEADER_H_ - by fact this is not true.
At LearnCpp.com | 1.10 — A first look at the preprocessor. Under Header guards, there are those code snippets:
add.h:
#include "mymath.h"
int add(int x, int y);
subtract.h:
#include "mymath.h"
int subtract(int x, int y);
main.cpp:
#include "add.h"
#include "subtract.h"
In implementing the header guard, it is mentioned as follows:
#ifndef ADD_H
#define ADD_H
// your declarations here
#endif
What could the declaration be here? And, should int main() come after #endif?
Is adding _H a convention or a must do thing?
Thanks.
The FILENAME_H is a convention. If you really wanted, you could use #ifndef FLUFFY_KITTENS as a header guard (provided it was not defined anywhere else), but that would be a tricky bug if you defined it somewhere else, say as the number of kittens for something or other.
In the header file add.h the declarations are literally between #ifndef and #endif.
#ifndef ADD_H
#define ADD_H
#include "mymath.h"
int add(int x, int y);
#endif
Finally, int main() shouldn't be in a header file. It should always be in a .cpp file.
To clear it up:
#ifndef ADD_H basically means "if ADD_H has not been #defined in the file or in an included file, then compile the code between #ifndef and #endif directives". So if you try to #include "add.h" more than once in a .cpp file, the compiler will see what the ADD_H was already #defined and will ignore the code between #ifndef and #endif. Header guards only prevent a header file from being included multiple times in the same .cpp file. Header guards don't prevent other .cpp files from including the header file. But all .cpp files can include the guarded header file only once.
The result of preprocessing one implementation (".cpp") file is a translation unit (TU).
Headers can include other headers, so a header may be indirectly included multiple times within the same TU. (Your mymath.h is an example of this.)
Definitions can only occur at most once per TU. (Some definitions must also not be in multiple TUs; this case is slightly different and not discussed here.)
The problem include guards solve is preventing multiple definition errors when a given header is included more than once within one TU.
Include guards work by "wrapping" the contents of the header in such a way that the second and subsequent includes are no-ops. The #ifndef/#define directives should be the first two lines of the file, and #endif should be the last.
Include guards are only used in headers. Do not define your main function in a header: put it in an implementation file.
If you have a header that will define a type and declare a function, but also needs a header itself:
#include "other_header.h"
struct Example {};
void f();
"Wrapping" it with include guards gives the complete contents of the file:
#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE
#include "other_header.h"
struct Example {};
void f();
#endif
The name used for the include guard must be unique, otherwise conflicting names will give confusing results. These names are only simple macros, and there is nothing in the language which enforces a certain style. However, project conventions usually impose requirements. There are several different include guard naming styles you can find here on SO and elsewhere; this answer gives good criteria and a good overview.
All the header guards do is to only allow your headers to be included once. (If they're included multiple times, they're ignored.)
The name you use doesn't matter, but it's conventional to use the file name in caps, including the extension like you demonstrated.
Your main should really be in a .cpp file, but if you're putting it in a header, put it inside the guards so it isn't declared multiple times.
No, the int main() goes in a .cpp. The declarations are the other stuff you were gonna put in the header. _H is a convention, you can see various header guard conventions around.
I declare a declaration in header file and definitions or int main() comes in source.cpp file.
_H is there to merely indicate that someone is going to include header files using include guards.
If you're on MSVC++ you can also use #pragma once
So I know how to place an include guard in my own header files with the standard
#ifndef ...
#define ...
Now, My question is about including libraries that are not my own. would be a good example. I have a header file which requires the use of string, so I do the following
foo.h
#ifndef FOO_H
#define FOO_H
#include <string>
... code etc ...
#endif
Now, if I have another header file called.. lets say, bar.h, which ALSO requires the use of <string>, how can i prevent multiple inclusions? Does the STL already have include guards in place?
The STL library also has include guards and any good library should do the same.
#ifndef _GLIBCXX_STRING
#define _GLIBCXX_STRING 1
This is from gcc's
Assuming that by "STL" you mean the C++ standard library, then you can refer to the C++ standard. §17.6.2.2/2 states:
A translation unit may include library headers in any order. 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.
This means that it is not necessary to guard against multiple inclusions of the same header.
Include guard use to guard the content inside the guard pair. You can check the system head file string, it also has the include guard. So, don't worry about multiple inclusions.
At LearnCpp.com | 1.10 — A first look at the preprocessor. Under Header guards, there are those code snippets:
add.h:
#include "mymath.h"
int add(int x, int y);
subtract.h:
#include "mymath.h"
int subtract(int x, int y);
main.cpp:
#include "add.h"
#include "subtract.h"
In implementing the header guard, it is mentioned as follows:
#ifndef ADD_H
#define ADD_H
// your declarations here
#endif
What could the declaration be here? And, should int main() come after #endif?
Is adding _H a convention or a must do thing?
Thanks.
The FILENAME_H is a convention. If you really wanted, you could use #ifndef FLUFFY_KITTENS as a header guard (provided it was not defined anywhere else), but that would be a tricky bug if you defined it somewhere else, say as the number of kittens for something or other.
In the header file add.h the declarations are literally between #ifndef and #endif.
#ifndef ADD_H
#define ADD_H
#include "mymath.h"
int add(int x, int y);
#endif
Finally, int main() shouldn't be in a header file. It should always be in a .cpp file.
To clear it up:
#ifndef ADD_H basically means "if ADD_H has not been #defined in the file or in an included file, then compile the code between #ifndef and #endif directives". So if you try to #include "add.h" more than once in a .cpp file, the compiler will see what the ADD_H was already #defined and will ignore the code between #ifndef and #endif. Header guards only prevent a header file from being included multiple times in the same .cpp file. Header guards don't prevent other .cpp files from including the header file. But all .cpp files can include the guarded header file only once.
The result of preprocessing one implementation (".cpp") file is a translation unit (TU).
Headers can include other headers, so a header may be indirectly included multiple times within the same TU. (Your mymath.h is an example of this.)
Definitions can only occur at most once per TU. (Some definitions must also not be in multiple TUs; this case is slightly different and not discussed here.)
The problem include guards solve is preventing multiple definition errors when a given header is included more than once within one TU.
Include guards work by "wrapping" the contents of the header in such a way that the second and subsequent includes are no-ops. The #ifndef/#define directives should be the first two lines of the file, and #endif should be the last.
Include guards are only used in headers. Do not define your main function in a header: put it in an implementation file.
If you have a header that will define a type and declare a function, but also needs a header itself:
#include "other_header.h"
struct Example {};
void f();
"Wrapping" it with include guards gives the complete contents of the file:
#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE
#include "other_header.h"
struct Example {};
void f();
#endif
The name used for the include guard must be unique, otherwise conflicting names will give confusing results. These names are only simple macros, and there is nothing in the language which enforces a certain style. However, project conventions usually impose requirements. There are several different include guard naming styles you can find here on SO and elsewhere; this answer gives good criteria and a good overview.
All the header guards do is to only allow your headers to be included once. (If they're included multiple times, they're ignored.)
The name you use doesn't matter, but it's conventional to use the file name in caps, including the extension like you demonstrated.
Your main should really be in a .cpp file, but if you're putting it in a header, put it inside the guards so it isn't declared multiple times.
No, the int main() goes in a .cpp. The declarations are the other stuff you were gonna put in the header. _H is a convention, you can see various header guard conventions around.
I declare a declaration in header file and definitions or int main() comes in source.cpp file.
_H is there to merely indicate that someone is going to include header files using include guards.
If you're on MSVC++ you can also use #pragma once
In c lets say we have 2 files
1.h
#include<2.h>
blah blah
and we have
2.h
#include<1.h>
code
How is this resolved??
Typically you protect your include file with an ifndef/define that corresponds to the file name. This doesn't prevent the file from being included again, but it does prevent the contents (inside the ifndef) from being used and triggering the recursive includes again.
#ifndef HEADER_1_h
#define HEADER_1_h
#include "2.h"
/// rest of 1.h
#endif
#ifndef HEADER_2_h
#define HEADER_2_h
#include "1.h"
// rest of 2.h
#endif
Okay, for the sake of completeness I'll begin by quoting tvanfosson's answer:
You should use include guards:
// header1.hpp
#ifndef MYPROJECT_HEADER1_HPP_INCLUDED
#define MYPROJECT_HEADER1_HPP_INCLUDED
/// Put your stuff here
#endif // MYPROJECT_HEADER1_HPP_INCLUDED
However include guards are not meant to solve circular dependencies issues, they are meant to prevent multiple inclusions, which is quite different.
base.h
/ \
header1.h header2.h
\ /
class.cpp
In this case (quite common), you only want base.h to be included once, and that's what include guards give you.
So this will effectively prevents the double inclusion... but you won't be able to compile!!
The problem can be illustrated by trying to reason as the compiler does:
Include "header1.hpp" > this defines the include guard
Include "header2.hpp
Try to include "header1.hpp" but doesn't because the include guard is already defined
Cannot correctly parse "header2.hpp" because the types coming from "header1.hpp" have not been defined yet (since it was skipped)
Back to "header1.hpp", and the types from "header2.hpp" are still missing since they could not be compiled, and thus it fails here too
In the end, you'll left with a big pile of error messages, but at least the compiler does not crash.
The solution is to somehow remove the need for this circular dependency.
Use forward declarations if possible
Split "header1.h" into 2 parts: the part independent from header2 and the other, you should only need to include the former in header2
And THIS will solve the circular dependency (manually) there is no magic going on in the compiler that will do it for you.
Since you posted your question under the c++ tag as well as c, then I am assuming you are using c++. In c++, you can also use the #pragma once compiler directive:
1.h:
#pragma once
#include "2.h"
/// rest of 1.h
2.h:
#pragma once
#include "1.h"
/// rest of 2.h
The result is the same. But there are some notes:
pragma once will usually compile a little faster since it is a higher level mechanism and doesn't happen at preprocessing like include guards
Some compilers have known bugs "dealing" with #pragma once. Though most if not all modern compilers will handle it correctly. For a detailed list see Wikipedia
Edit: I think the directive is also supported in c compilers but have never tried it, and besides, in most c programs I've seen, include guards are the standard (maybe due to compiler limitations handling the pragma once directive?)
Circular inclusions must be eliminated, not "resolved" with include guards (as the accepted answer suggests). Consider this:
1.h:
#ifndef HEADER_1_h
#define HEADER_1_h
#include "2.h"
#define A 1
#define B 2
#endif // HEADER_1_h
2.h:
#ifndef HEADER_2_h
#define HEADER_2_h
#include "1.h"
#if (A == B)
#error Impossible
#endif
#endif // HEADER_2_h
main.c:
#include "1.h"
This will throw the "Impossible" error at compile time, because "2.h" fails to include "1.h" due to include guards, and both A and B become 0. In practice, this leads to hard to track errors which appear and disappear depending on the order in which header files are included.
The right solution here would be to move A and B to "common.h" which then could be included in both "1.h" and "2.h".