Show Lecture.IncludeGuards as a slide show.
CS253 Include Guards
Multiple Inclusion
- #include-ing a file twice can cause problems.
Remember what #include does. It literally copies everything in the
file into the current input stream, to be compiled along with the contents of
the current file. If you #include a file twice, you compile it twice.
- If that file defines a class, you get an error
saying that the class is already defined.
class Foo {
};
class Foo { // 🦡
};
c.cc:4: error: redefinition of ‘class main()::Foo’
- Yeah, so? What sort of fool would #include something twice?
How it happens
main.cc
:
#include "foo.h"
#include "bar.h"
foo.h
:
#include <string>
bar.h
:
#include <string>
Both foo.h
and bar.h
use strings, so they both
#include <string>
. However, we don’t want to have an error
complaining that class string
is redefined. How do we cure
this?
The solution
string:
#ifndef STRING_INCLUDED
#define STRING_INCLUDED
class string {
…
};
#endif /* STRING_INCLUDED */
- The first time <string> was #included, the symbol
STRING_INCLUDED
was not defined. Therefore the rest of the
compile-time #ifndef (if not defined)
conditional compilation was processed.
- The preprocessor symbol
STRING_INCLUDED
was defined.
- The
class string
was defined.
- Next time,
STRING_INCLUDED
was defined, so the file had no effect.
It was as if an occult hand had prevented the
file from being processed a second time.
Non-standard solutions
- There exists a non-standard solution,
#pragma once
.
Avoid it.
- It’s non-standard, and so doesn’t work everywhere.
- Include guards are standard, and so work everywhere.
- For current compilers, include guards are just as fast
as
#pragma once
.