9

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.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
jayjyli
  • 771
  • 3
  • 11
  • 23
  • 5
    See [here](http://stackoverflow.com/questions/228783) for a discussion of the rules your tutor is breaking, and [here](http://stackoverflow.com/questions/3345159) for an example what could go wrong if you break them. Also, include guards go *inside* the header. – Mike Seymour Apr 09 '12 at 17:27
  • As it is, the inculded code makes no sense: you cannot `#define` a string literal. Did you mean `#include "header.h"` (the original wording) or `#define HEADER_H` (what usually goes inside a header preamble)? – Attila Apr 13 '12 at 20:07

4 Answers4

18

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.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 1
    ...and if it isn't an implementation header file, it should avoid identifiers containing an underscore followed by another underscore or capital letter. – Jerry Coffin Apr 09 '12 at 17:23
  • @JerryCoffin: "containing", or "starting with"? – Oliver Charlesworth Apr 09 '12 at 17:25
  • For C, starting. For C++, containing a doubled underscore is verboten as well (but underscore followed by cap is allowed as long as it's not at the beginning). – Jerry Coffin Apr 09 '12 at 17:26
  • @JerryCoffin: Interesting. Oh well, I think I'll stick with my summary in my answer of "various subtle rules". – Oliver Charlesworth Apr 09 '12 at 17:27
  • 2
    "Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use. Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace." §17.6.4.3.2 in n3290 C++ – Mat Apr 09 '12 at 17:29
5

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.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
1

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.

Marc
  • 16,170
  • 20
  • 76
  • 119
  • 4
    Not true. Names beginning with two underscores are reserved for the implementation (in C99, at least). – Oliver Charlesworth Apr 09 '12 at 17:24
  • 1
    +1: Actually answers OP's question instead of stating the "usual" way of doing things. – Thomas Eding Apr 09 '12 at 17:24
  • 4
    It's not just a convention. Using an identifier starting with a `__` makes your code's behavior undefined. The implementation (either the compiler or the standard library) is free to use the name `__HEADER_H__` for its own purposes; if it does so, your own use of that identifier could mean literally *anything*. – Keith Thompson Apr 09 '12 at 17:25
  • @trinithis: Using such identifiers puts you into the realm of undefined behaviour, although usually what that means in this case is that in certain situtaions, you'll end up with tricky-to-diagnose compile-time errors. – Oliver Charlesworth Apr 09 '12 at 17:26
  • @OliCharlesworth I didn't know that, thank you. But basically you could put anything there and it will work too, right? – Marc Apr 09 '12 at 17:27
  • @Marc: So long as you avoid the rules about names with underscores, then it doesn't really matter. Although obviously you should try to pick something that isn't likely to clash with anything else. – Oliver Charlesworth Apr 09 '12 at 17:30
  • @Marc since your answer is wrong, maybe you should add a note, to avoid confusion for future readers. – juanchopanza Apr 09 '12 at 21:17
1

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.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631