-1

For a file name a.h... I've always used

#ifndef A_H
#define A_H
#endif

but now I see in tutorials

#ifndef __A_H_INCLUDED__ 
#define __A_H_INCLUDED__ 
#endif

and also

#ifndef _A_H_INCLUDED 
#define _A_H_INCLUDED
#endif

So I was wondering what's going on... Has this changed in never versions of C++ or is this compiler dependent?

I use MinGw (gnu gcc g++) and msvc...

Edit:

In case there is confusion as to why this is asked, I believe that this is quite confusing to novices. For example, for a file named a.h we don't say

#ifndef a.h
#define a.h

or even

#ifndef A_H
#define A_H a.h

that would make sense to me.

instead we say A_H... or one of the variants above. Therefore, I would think not just any syntax is ok. I always used to think that it has to be the file name in caps and that the period has to be replaced with an _. This is how I saw it being taught for years. No I see words like _INCLUDED ... which are obviously not part of the a.h file name in any way... this is confusing... how does the compiler reconcile that A_H_INCLUDED refers to a.h? I don't see why this is down voted I think it's quite confusing.

Also, one person has stated that some of these variants are not standards compliant, therefore I think it is a valid question and should not be down voted.

Or is it the case that #define A_H dumps all the code from the header file into the A_H macro? But I thought that define ends at new line character... in which case we define A_H with no value. In that case A_H is just a name with no value and the question remains how does the compiler know you're talking about file a.h when you use a funky empty marco variable like A_H_DINGDONG ?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
code
  • 1,056
  • 10
  • 22
  • What are you talking about? The macro name has always been completely arbitrary. Choose whatever you like. Other than the name, I see no difference between the three variants. However, I'd suggest refraining from names that begin with `__` or with `_`+capital letter - these are reserved. – AnT stands with Russia Nov 10 '16 at 23:26
  • avoid beginning with underscore yours may interfere with system libraries – Raindrop7 Nov 10 '16 at 23:28
  • [The macro names from those tutorials are not standard-compliant](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). Stick with what you were doing. – WhozCraig Nov 10 '16 at 23:30
  • 1
    You can use whatever marco definition you like. There is also [#pragma once](https://en.wikipedia.org/wiki/Pragma_once), which is not standard, but is supported by virtually every C/C++ compiler. – sastanin Nov 10 '16 at 23:33
  • eg if your macro: `__WIN32` then a you are facing a collision – Raindrop7 Nov 10 '16 at 23:37

5 Answers5

1

The #ifndef, #define, and #endif are the syntax parts that matter. What naming convention you use is up to you.

Setleaf
  • 75
  • 1
  • 7
1

These are just names like variable names.

Double underscore names are reserved, so strictly speaking #define __A_H_INCLUDED__ is undefined behavior and underscore + capital letter shouldn't be used either.

You just want to avoid naming collisions with your other code and the standard and using the file name usually ensures that.

nwp
  • 9,623
  • 5
  • 38
  • 68
1

There's been no relevant change in the language. The identifier used in an include guard is just an identifier. In fact the entire include guard mechanism is not defined by the language; it's just a convention.

The issue is that identifiers starting with two underscores, or with one underscore and an uppercase letter, are reserved to the implementation. That means that if you use the name __FOO_H__ in your code, it's at least possible that the compiler has already predefined it for its own internal purposes, and your code could break in some undetermined manner.

Tutorials that tell you to write:

#ifndef __A_H_INCLUDED__ 
#define __A_H_INCLUDED__ 
#endif

are giving you poor advice.

One more subtlety: macro names starting with E and a digit, or E and an uppercase letter, are reserved for use in the <errno.h> / <cerror> header. So if your header file is called earth.h and you write:

#ifndef EARTH_H
#define EARTH_H
#endif

then you could in principle collide with an EARTH_H error number.

That's not likely to happen, and the _H suffix is almost certainly enough to prevent it, but a convention I use to avoid it altogether is:

#ifndef H_EARTH
#define H_EARTH
#endif

You suggest:

#define a.h

A macro name must be a single identifier. That actually defines the macro a with the value .h.

#define A_H a.h

Since the macro is only tested using #ifndef, it doesn't matter at all what value it has, only whether it's defined or not.

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

It comes down to personal/organizational preference although there are some conventions around this. In general it doesn't really matter what you put here as long as it's not used anywhere else.

Some examples:

  • A_H: Looks similar to a constant you would use in code.
  • A_H_: Would be better because you're not likely to see a constant with an underscore at the end.
  • _A_H_INCLUDED: At first blush this looks better because it's similar in appearance to a private file-scoped variable. But this is a problem because underscore + capital letter are reserved so this is not an appropriate macro.
  • A_H_INCLUDED: Without the leading underscore, clear purpose and not likely to conflict with anything else in your program.
  • __A_H_INCLUDED__: Double underscores are reserved; do not use.

Also, it's not part of the standard, but #PRAGMA ONCE is widely supported and accomplishes the same thing without needing to worry about naming conventions at all.

Mike
  • 1,647
  • 15
  • 14
  • 1
    `_A_H_INCLUDED` Not better. Worse. Underscore followed by capital is reserved or use by the implementation. More here: [What are the rules about using an underscore in a C++ identifier?](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) Concept right though. The less likely to be accidentally repeated, the better. – user4581301 Nov 10 '16 at 23:57
  • 1
    The last two names are reserved for use by the implementation and should not be used in your code. – Pete Becker Nov 11 '16 at 00:00
0
#define A_H

doesn't have any connection with file a.h.

Inside dir/filename.h, you can:

#ifndef WHATEVER_NOT_DEFINED_HENCE_HAVE_DIR_FILENAME_H_IS_GOOD_
#define WHATEVER_NOT_DEFINED_HENCE_HAVE_DIR_FILENAME_H_IS_GOOD_
#endif

but you can't use this

#define WHATEVER_HAS_DOUBLE_UNDERSCORE_LIKE_THIS_IS_BAD__
#define __OR_LIKE_THIS_IS_BAD
#define OR_LIKE__THIS_IS_BAD

and you can't have an identifer starts with undercore and followed by capital character like this:

#define _LIKE_THIS_IS_BAD
Danh
  • 5,916
  • 7
  • 30
  • 45