Why does clang's stdbool.h contain #define fal

2019-02-07 15:32发布

问题:

After being pointed there by a compiler error, I noticed clang's stdbool.h file includes (among other things) the following lines:

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

They're contained in an #ifdef block that enforces __cplusplus indirectly, hence the c++ tag even though stdbool.h is a C header.

What's the need for those defines? I imagine they're required for some preprocessor-related reason but I'd be interested to know what part of the standard or which technical reason makes it so clang has to include those.

回答1:

stdbool.h is a C header, not a C++ header. It is not usually found in C++ programs because true and false are already keywords in C++.

Consequently, if a C++ program includes stdbool.h it is a fairly clear indication that it is a ported-over C program (e.g. a C program that is being compiled as C++). In this case, G++ supports stdbool.h in C++ mode as a GNU extension, per the comments from the GCC stdbool.h:

/* Supporting <stdbool.h> in C++ is a GCC extension.  */
#define _Bool        bool
#define bool        bool
#define false        false
#define true        true

...

/* Signal that all the definitions are present.  */
#define __bool_true_false_are_defined        1

Clang, likewise, supports stdbool.h in C++ for compatibility with G++. The values are intentionally defined here to match the built-in C++ type rather than the traditional C99 definitions. They are defined as macros presumably to provide some compatibility with the C99 standard, which requires:

The header shall define the following macros: bool, true, false, __bool_true_false_are_defined.

An application may undefine and then possibly redefine the macros bool, true, and false.



回答2:

It was added to suport GNU mode in C++, as we can see from this patch [cfe-commits] r115028 :

Define _Bool, bool, true, and false macros in when we're in a GNU-compatible C++ dialect. Fixes <rdar://problem/8477819>.

so gcc supports this as an extension and this modification was made to support that extension.

Although I can not find the original problem report mentioned in the patch.

This is non-conforming as we can see from the draft C++11 standard section 18.10 Other runtime support [support.runtime]:

The header <cstdbool> and the header <stdbool.h> shall not define macros named bool, true, or false.

but gcc is not meant to be strictly conforming in GNU mode.

stdbool.h is part of C99 and so was not supported by the C++ standard until C++11 which in Annex D says:

For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides the 25 C headers, as shown in Table 154

and includes <stdbool.h>.