Can/should I type whatever I want after #ifndef?

410 Views Asked by At

Example:

#ifndef HEADER_h
#define HEADER_h

#endif

Instead of HEADER_h, can I do the following?

#ifndef HEADER

or

#ifndef LIBRARY

or

#ifndef SOMETHING

or

#ifndef ANOTHERTHING

etc.

4

There are 4 best solutions below

3
lubgr On BEST ANSWER

Yes, you can name the include guard symbol whatever you want, but bear in mind that they are supposed to be unique across headers. You definitely don't want a header

// first.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H

void foo();

#endif

and another one

// second.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H

void bar();

#endif

When you include both in one translation unit, one will "win" and its declarations will be visible, e.g.

// main.cpp

#include "first.h" // now, NON_UNIQUE_H is defined
#include "second.h" // NON_UNIQUE_H already there, doesn't do anything

int main(int, char**)
{
    bar(); // error, won't compile, bar() isn't declared
}

Besides the necessity to circumvent such scenarios, it's best to stick to some convention throughout your project. One classical way of doing it is to convert the header file base name to upper case and append _H. If you have header files with the same base name in different directories, you can include the directory name, e.g. SUBDIR_FOO_H and OTHERSUBDIR_FOO_H. But this is up to you.

5
Sergey On

You can use a construction like

#if !defined(HEADER) || !defined(LIBRARY)

At your question, you are using

#ifndef HEADER_h
#define HEADER_h

#endif

It's the same as "#pragma once" And yes, you can use different names of defines. In your case, LIBRARY, SOMETHING, HEADER_h - defines, that you can set in code(#define MY_VAR_NAME) or via compiler options(flag -DMY_VAR_NAME).

2
Lightness Races in Orbit On

Header guards are just a convention, a "trick", making use of preprocessor conditions. In using a header guard you are creating a macro with a name, and checking whether that macro was already defined.

There is nothing magical about this macro that binds it to the filename of a header, and as such you can call it whatever you want (within reason).

That doesn't mean that you should write #ifndef URGLEBURGLE, though. You want the name to be useful and unique, otherwise there's not much point.

Typically something like #ifndef [PROJECTNAME]_[FILENAME]_INCLUDED is a good idea.

0
463035818_is_not_an_ai On

Your example is a so-called header guard that allows us to ensure the contents of the header are included only once. However, that is not the only use of #ifndef.You can use #ifndef for conditional compilation as in

 #ifndef NO_DEBUG
 do_some_debug_stuff();
 #endif

So it is not only for header guards, but in general you have to carefully choose the name of the symbols you are introducing to prevent they are clashing with symbols defined elsewhere. It is just that header guards are so common that certain conventions exist (eg using FOLDER_FILENAME_H is usually sufficient to ensure uniqueness). And you need to be aware that certain names are reserved (eg starting with two underscores or underscore followed by capital letter).