0

In a C program, one of the *.h file was written as follows :

#ifndef T2_A
#define T2_A

// code segment
// code segment
// code segment

#endif

The first line was trying to evaluate if macro T2_A is defined; if not, it should be defined. But the second line is just #define T2_A, and it does not assign any value to it.

I'm kind of confused if it's correct, because my assumption is that we need to assign some value to T2_A in this #define directive.

user297850
  • 7,705
  • 17
  • 54
  • 76
  • 1
    This is an include guard. The point is to prevent the body of the `.h` file from being processed multiple times. It is not required to assign anything to a `#defined` name. – jkb Apr 27 '21 at 05:04
  • 3
    Macros don't need to have any replacement text. The purpose of that pattern you found is just to detect if that file was already included before. That is called "include guards". – Gerhardh Apr 27 '21 at 05:04
  • Does this answer your question? [What exactly do C include guards do?](https://stackoverflow.com/questions/27810115/what-exactly-do-c-include-guards-do) – mediocrevegetable1 Apr 27 '21 at 05:12
  • It does have a "value", but you can't see it (or write it). It expands to nothing. – molbdnilo Apr 27 '21 at 07:28
  • `#ifdef`/`#ifndef` checks if a macro is defined. `#if` checks its value. You are using `#ifndef` so the value doesn't matter. – Lundin Apr 27 '21 at 12:44

2 Answers2

2

It’s a protection:

Let’s say t2.h is included in main.c

#include “t2.h”

The preprocessor copies it’s contents into main.c so it now looks like:

#ifndef T2_A
#define T2_A
...
#endif
(code of main.c)

T2_A is clearly not defined - we execute the code inside of the if statement. First, we define T2_A - from now on, this if statement will be always false, until we say #undef T2_A. If main.c included a header t3.h, which included t2.h, you would include the file twice but execute only once due to the protection.

Without that, the above scenario would produce compiler errors because of redefinition (same code with the same function declarations ran twice). With modern compilers and in C++, you can replace it with a simpler and faster:

#pragma once
1

As multiple comments have already said, the purpose of this structure is as an "include guard". This ensures that a header is not included twice in same translation unit.

Say you have a.h which includes t.h file, also b.h which includes t.h file.

When a foo.cpp include both a.h and b.h two copies of t.h file is included, but due to this include guard, t.h will only be compiled once. This will save in compile time and prevent multiple definition or declaration errors.

Regarding #define needing a value, it is not so. in this case if you use T2_A somewhere in your code, it will be replaced with nothing, not even a space.

These can be usefull in diagnostics like so:

#ifdef _DEBUG
#define LOG(x)    std::cout << (#x) << " " << (x)
#else
#define LOG(x)
#endif

Here you may insert LOG(x) anywhere in your code to display the value passed to the macro. When _DEBUG is define (ie building for diagnostics) the program will log values. But when building for final release, _DEBUG is not defined and all logging statements are replaced with nothing, like it was never there.

WARhead
  • 643
  • 5
  • 17