Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Header Guarding questions in C++

Tags:

c++

macros

header

I am new to writing my own headers, but due to necessity, I must learn.

I am writing a header, and I'm trying to grok header guards. Is there a difference between having one or two underscores before and after the included header file?

Take this hypothetical example: x.h

//x.h
#ifndef __X_H_INCLUDED__
#define __X_H_INCLUDED__
//functions n stuff
#endif

versus:

//x.h
#ifndef _X_H_INCLUDED_
#define _X_H_INCLUDED_
//functions n stuff
#endif

Is one more or less right than the other? Is there a difference?

like image 985
j0h Avatar asked Dec 18 '22 23:12

j0h


2 Answers

As per C++11 17.6.4.3.2 Global names (though this restriction has been around for a while):

Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter 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.

So you really should be using neither if you want your software to be portable though, having said that, plenty of people do use both varieties.

It would be "safer" to use something like GUARD_X_H or X_H_INCLUDED though, of course, you still need to be wary of clashes. You might take the Java way and end up with macros like:

AU_COM_POWERFIELD_DATASTRUCTURES_TREES_BALANCED_BTREE_H

as long as you stay below the implementation limits for macro names (which, from memory, is at least 1024 characters).

Alternatively, if you want to sacrifice portability (but not much portability since it's supported in a great many compilers), you could look into #pragma once, where you don't have to worry about coming up with unique names.

like image 101
paxdiablo Avatar answered Jan 03 '23 07:01

paxdiablo


From the 2003 C++ Standard (these rules still apply):

17.4.3.2.1 Global names [lib.global.names]

Certain sets of names and function signatures are always reserved to the implementation:

Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter (2.11) 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.165 165) Such names are also reserved in namespace ::std (17.4.3.1).

like image 33
shafeen Avatar answered Jan 03 '23 08:01

shafeen