开发者

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
开发者_C百科
// 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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜