-1

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.

Duck Dodgers
  • 3,409
  • 8
  • 29
  • 43
  • 1
    You can put whatever you want, but it shouldn't clash with anything else that might exist, including internal identifiers used by the compiler or other libraries. `LIBRARY` or `HEADER` seems too broad for me. If it's `MY_CLASS_H` then surely there won't be any conflict. – Blaze Feb 05 '19 at 10:33
  • You can write almost anything. You should not write underscore followed by another underscore or capital letter (__x and _X.. should not be used), because those are reserved for compiler and system libraries. – Dialecticus Feb 05 '19 at 10:39
  • Use the answer section for answers please folks – Lightness Races in Orbit Feb 05 '19 at 10:43

4 Answers4

2

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.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

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.

lubgr
  • 37,368
  • 3
  • 66
  • 117
0

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).

Sergey
  • 96
  • 5
  • 1
    isnt `#if !defined(HEADER) || !defined(LIBRARY)` pretty useless as header guard? I cannot imagine how this would help to include a header only once, unless in the same header you define both symbols (`HEADER` and `LIBRARY`, which makes the `||` superfluous) – 463035818_is_not_an_ai Feb 05 '19 at 10:52
  • An include guard is not quite the same as `#pragma once`. Although supported by virtually all modern compilers, `#pragma once` is not actually supported by the C++ standard. In comparison, an include guard uses capabilities required by the standard (as long as care is taken to ensure the macro is unique, and to avoid use of reserved names). Practically, some compilers have subtle bugs in their support of `#pragma once`. – Peter Feb 05 '19 at 10:58
  • @Peter, you are right. #pragma once is not a part of C++ standard. But Microsoft VC++(after 4.2), GCC(after 3.4), CLang, ARM/IAR support this directive. But for now, most of the compilers support it. Using include guard is more "safe" variant, ofc. – Sergey Feb 05 '19 at 11:06
  • @user463035818, using a construction with multiple checks of definitions is using, for example, when you need to check compiler type/OS-type or another option when logic inside of this header guard depends on composite condition. For example, the file will be included if you are using MinGW-compiler OR GCC-compiler. – Sergey Feb 05 '19 at 11:13
  • hm ok, so its not just a header guard but for more complicated situations. Btw if it is supposed to be header guards plus checking for what compiler is used it should probably be `&&` not `||`. With `||` I still dont get how this can function as a header guard – 463035818_is_not_an_ai Feb 05 '19 at 11:21
0

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).

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185