Header guards in C++ and C
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