How are circular #includes resolved? - c++

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".

Related

Is it legal for a compiler to ignore an #include directive?

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.

Can/should I type whatever I want after #ifndef?

Example:
#ifndef HEADER_h
#define HEADER_h
#endif
Instead of HEADER_h, can I do the following?
#ifndef HEADER
or
#ifndef LIBRARY
or
#ifndef SOMETHING
or
#ifndef ANOTHERTHING
etc.
Header guards are just a convention, a "trick", making use of preprocessor conditions. In using a header guard you are creating a macro with a name, and checking whether that macro was already defined.
There is nothing magical about this macro that binds it to the filename of a header, and as such you can call it whatever you want (within reason).
That doesn't mean that you should write #ifndef URGLEBURGLE, though. You want the name to be useful and unique, otherwise there's not much point.
Typically something like #ifndef [PROJECTNAME]_[FILENAME]_INCLUDED is a good idea.
Yes, you can name the include guard symbol whatever you want, but bear in mind that they are supposed to be unique across headers. You definitely don't want a header
// first.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H
void foo();
#endif
and another one
// second.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H
void bar();
#endif
When you include both in one translation unit, one will "win" and its declarations will be visible, e.g.
// main.cpp
#include "first.h" // now, NON_UNIQUE_H is defined
#include "second.h" // NON_UNIQUE_H already there, doesn't do anything
int main(int, char**)
{
bar(); // error, won't compile, bar() isn't declared
}
Besides the necessity to circumvent such scenarios, it's best to stick to some convention throughout your project. One classical way of doing it is to convert the header file base name to upper case and append _H. If you have header files with the same base name in different directories, you can include the directory name, e.g. SUBDIR_FOO_H and OTHERSUBDIR_FOO_H. But this is up to you.
You can use a construction like
#if !defined(HEADER) || !defined(LIBRARY)
At your question, you are using
#ifndef HEADER_h
#define HEADER_h
#endif
It's the same as "#pragma once"
And yes, you can use different names of defines. In your case, LIBRARY, SOMETHING, HEADER_h - defines, that you can set in code(#define MY_VAR_NAME) or via compiler options(flag -DMY_VAR_NAME).
Your example is a so-called header guard that allows us to ensure the contents of the header are included only once. However, that is not the only use of #ifndef.You can use #ifndef for conditional compilation as in
#ifndef NO_DEBUG
do_some_debug_stuff();
#endif
So it is not only for header guards, but in general you have to carefully choose the name of the symbols you are introducing to prevent they are clashing with symbols defined elsewhere. It is just that header guards are so common that certain conventions exist (eg using FOLDER_FILENAME_H is usually sufficient to ensure uniqueness). And you need to be aware that certain names are reserved (eg starting with two underscores or underscore followed by capital letter).

#ifndef syntax for include guards in C++

I'm currently studying for a CS course's final exam and I've run into a minor (maybe major?) issue regarding the syntax of C++ #ifndef.
I've looked at the syntax for #infndef when using it as an #include guard, and most on the web seem to say:
#ifndef HEADER_H
#define "header.h"
...
#endif
But my class's tutorial slides show examples as:
#ifndef __HEADER_H__
#define "header.h"
...
#endif
I was wondering what (if any) the difference was between the two. The exam will most likely ask me to write an #include guard, and I know conventional wisdom is to just go with what the prof / tutor says, but if there's a difference during compilation I'd like to know.
The usual practice is to do neither, and put the include guard inside the header file, as it reduces repetition. e.g.:
header.h
#ifndef HEADER_H
#define HEADER_H
// Rest of header file contents go here
#endif
Precisely what you use as the macro name is down to your particular coding standard. However, there are various subtle rules in the C and C++ standards that prevent you from using identifiers beginning with underscores,1 so you should avoid __HEADER_H__, just to be on the safe side.
It's also worth mentioning that you should pick something that's unlikely to clash with anything else in your codebase. For example, if you happened to have a variable called HEADER_H elsewhere (unlikely, I realise), then you'd end up with some infuriating errors.
1. See e.g. section 7.1.3 of the C99 standard.
Names starting with a double underscore are reserved for the implementation, so I would advise against using __SOMETHING in your include guards. Also, try to chose names that make clashes unlikely. So it seems your class' tutorials are wrong on at least two counts. See this humorous article for example.
An argument for putting the include guards in the file that includes the header, rather than in the header itself, is that if the file has already been included the compiler (specifically the preprocessor) doesn't have to open and read the include file again.
That's a weak argument. In practice, the time saved is trivial, and the potential for error is large.
In your example:
#ifndef HEADER_H
#include "header.h"
...
#endif
you don't show us the #define HEADER_H. Is it somewhere in header.h? If so, how do you know that the author of header.h chose to use HEADER_H as the name of the include guard macro? What if it changes to something else later?
If you decide to put the include guard in the including file, you should define the macro there as well:
#ifndef HEADER_H
#include "header.h"
#define HEADER_H
#endif
But, as other answers have already said, it's much better to put the guard in the header itself:
header.h :
#ifndef HEADER_H
#define HEADER_H
/* contents of header.h */
#endif
and then the include simply has:
#include "header.h"
and has one less piece of information to worry about.
There's no difference if you don't use underscore in variable names anywhere else, it's only a naming convention.
You just need to put something unique.

C++ include guard

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.

how to avoid header coupling

I am trying to address this issues because I can not seem to find a good resource online that does so.
I do not fully understand the issue cause I never got it resolved so I will try to describe it as best as possible.
Awhile ago I had an issue where headers were being ignored because "They were called once already and therefore when they were called again by another document, it was being ignored and therefore an error was being thrown"
I never fully understood that because you can call a header more then once without errors being thrown
header1.h
#ifndef _FCLASS_
#define _FCLASS_
class firstClass {
...//declaration
}
#endif
header2.h
#ifndef _SCLASS_
#define _SCLASS_
#include "header1.h"
class SecondClass:firstClass{
...//declaration
}
#endif
header3.h
#ifndef _TCLASS_
#define _TCLASS_
#include "header1.h"
class thirdClass:firstClass{
...//declaration
}
#endif
In the above example, the header1 class was called twice, and no errors should of been thrown. Even though header1 was declared once, it could be used by multiple headers.
So my question is , in what scenarios, can a header actually be ignored by a document if it was already declared once.
Does this type of issue only apply to .cpp files that include headers ??
This most commonly happens when there's a header cycle (two headers including each other being the most likely case).
Just for illustration, real examples are usually more complex.
A.h:
#ifndef A_INCLUDED
#define A_INCLUDED
#include "B.h"
class A
{
};
class C
{
B b;
}
#endif
B.h:
#ifndef B_INCLUDED
#define B_INCLUDED
#include "A.h"
class B : public A
{
};
#endif
In this case, regardless of which header you include, there's a circular dependency that prevents it from compiling. If you include A.h, it includes B.h. B.h then includes A.h but the include guard prevents it from being included again. So then it continues compiling B.h and fails when it doesn't know about class A. The reverse situation applies if including B.h first.
EDIT: I should have mentioned that this is typically solved by refactoring logic out of one or both headers into another header, and/or using forward declarations instead of actual includes.
I can think of one scenario. If header1.h has sections that are excluded by conditional compilation and those conditions change by declarations in subsequently included header files. Later inclusions of header1.h will be skipped by its include guard and it won't be able to declare the conditional sections which could lead to errors.