7

I ran into these lines:

#define bool  bool
#define false false
#define true  true

I don't think I need to say more than "wtf?", but just to be clear: What is the point of defining something to itself?

The lines come from clang stdbool.h

msc
  • 33,420
  • 29
  • 119
  • 214
klutt
  • 30,332
  • 17
  • 55
  • 95
  • Just curious: where have you seen this? – Jabberwocky Oct 17 '17 at 19:31
  • https://stackoverflow.com/questions/46797609/why-do-major-compilers-use-typedef-for-stdint-h-but-use-define-for-stdbool-h – klutt Oct 17 '17 at 19:32
  • Same question : https://stackoverflow.com/questions/35038583/define-bool-bool-says-qtcreator-when-i-hover-bool-i-tracked-that-into-boost – msc Oct 17 '17 at 19:33
  • 3
    That basically just stops macro expansion. Recursive macro references are detected, and block further expansion. – Tom Karzes Oct 17 '17 at 19:33
  • 1
    @rsp that's a C++ link, not C. – Tom Karzes Oct 17 '17 at 19:34
  • 1
    So that you can feature-test with `#ifdef`. Note that the code you are looking at is only for C++, and specifically gcc extensions to old versions of the C++ standard. – rici Oct 17 '17 at 19:38
  • @rici Are you saying that I should retag? – klutt Oct 17 '17 at 19:41
  • 1
    @klutt: that is up to you; I'm just putting the cited code in context. Observe the #ifndef __cplusplus / #else conditionals – rici Oct 17 '17 at 19:43
  • @rici If I should retag or not does not seem to be a matter of opinion to me. That's why I'm asking for the answer. :) – klutt Oct 17 '17 at 20:02
  • @klutt: If you ask the question w.r.t. C, the answer is "that code is incompatible with what the standard requires of stdbool.h" (and so if you have a stdbool.h which performs those assignments, it is not conformant). See section 7.18. If, on the other hand, you ask the question w.r.t. to the current C++ standard, you get a different reason for the definitions to be invalid (keywords are not allowed to be used as macro names, and `cstdbool` is not allowed to define those macros. 17.5.4.3.2 & 18.10.3). But if you asked w.r.t. a very old C++ version, you might get the answer you accepted. – rici Oct 17 '17 at 21:21
  • @klutt: So my opinion is that you must specify the context in which you are asking the question, but that both C and C++ contexts are valid (but different) questions. – rici Oct 17 '17 at 21:22
  • Also, if this question is not specifically about bool, true and false, but rather the general question in the title, then it is a duplicate of https://stackoverflow.com/questions/42315475/why-define-a-macro-with-the-same-name-and-content-in-c/42317302#42317302 – rici Oct 17 '17 at 21:46

3 Answers3

9

The C and C++ standards explicitly allow that (and requires that there is no infinite expansion)

BTW, function-like recursive (or self-refential) macros are even more useful:

#define puts(X) (nblines++,puts(X))

(the inner puts is a call to the standard puts function; the macro "overloads" such further calls by counting nblines)

Your define could be useful, e.g. with later constructs like #ifdef true, and it can't be a simple #define true because that would "erase" every further use of true, so it has to be exactly#define true true.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 3
    To add to this, it does not interfere with otherwise using the tokens in the code. If it had just done `#define true` to allow the for `#ifdef true`, then you could not, say, use `true` as the name of a variable. – Christian Gibbons Oct 17 '17 at 19:38
  • I must say I don't fully see the use. Why not simply use `#define true` instead of `#define true true`? – klutt Oct 17 '17 at 19:43
  • 1
    @klutt Because then all uses of `true` would be erased. With `#define true true`, you can do the macro test and still use `true` as if there never was a macro defined over it. – Petr Skocik Oct 17 '17 at 19:45
  • Quibble: Neither C nor C++ standards allow `#define bool bool`, specifically, except that you could do it in C if you don't `#include ` – rici Oct 17 '17 at 21:24
7

It allows the user code to conditionally compile based on whether those macros are or aren't defined:

#if defined(bool)
    /*...*/
#else
    /*...*/
#endif

It basically saves you from having to pollute the global namespace with yet another name (like HAVE_BOOL), provided that the implementation lets its users know that iff it provides a bool, it will also provide a macro with the same name that expands to it (or the implementation may simply use this internally for its own preprocessor conditionals).

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
4

It is called self referential Macros.

According to gcv reference :

A self-referential macro is one whose name appears in its definition. Recall that all macro definitions are rescanned for more macros to replace. If the self-reference were considered a use of the macro, it would produce an infinitely large expansion. To prevent this, the self-reference is not considered a macro call. It is passed into the preprocessor output unchanged.

Reference example :

One common, useful use of self-reference is to create a macro which expands to itself. If you write

#define EPERM EPERM

then the macro EPERM expands to EPERM. Effectively, it is left alone by the preprocessor whenever it’s used in running text. You can tell that it’s a macro with ‘#ifdef’. You might do this if you want to define numeric constants with an enum, but have ‘#ifdef’ be true for each constant.

Community
  • 1
  • 1
msc
  • 33,420
  • 29
  • 119
  • 214
  • I can understand that use, that a self-referential macro would terminate on such occasion. What I could not understand at first was the use of writing this variant as actual code. – klutt Oct 17 '17 at 19:54