为什么clang的stdbool.h包含#define false false

时间:2015-06-16 18:11:22

标签: c++ clang language-lawyer

在被编译错误指向后,我注意到clang的stdbool.h文件包括(除其他外)以下几行:

def __getattribute__(self, name):
    print("get", name)
    return object.__getattribute__(self, name)

它们包含在#define bool bool #define false false #define true true 块中,间接强制执行#ifdef,因此即使__cplusplus是C头,也是c ++标记。

这些定义需要什么?我想他们需要一些与预处理器相关的原因,但我有兴趣知道标准的哪个部分或者哪个技术原因使得clang必须包括那些。

2 个答案:

答案 0 :(得分:50)

stdbool.h是C头,而不是C ++头。它通常不会出现在C ++程序中,因为truefalse已经是C ++中的关键字。

因此,如果C ++程序包含stdbool.h,则相当清楚地表明它是一个移植的C程序(例如,正在编译为C ++的C程序)。在这种情况下,根据GCC stdbool.h的注释,G ++在C ++模式下支持stdbool.h作为GNU扩展:

/* 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在C ++中支持stdbool.h以与G ++兼容。 这里有意定义这些值以匹配内置C ++类型而不是传统的C99定义。它们被定义为宏,可能是为了提供与C99 standard的一些兼容性,这需要:

  

标题应定义以下booltruefalse__bool_true_false_are_defined

     

应用程序可能会取消定义,然后可能会重新定义宏bool,true和false。

答案 1 :(得分:18)

它被添加到了支持GNU mode in C++,正如我们从此补丁[cfe-commits] r115028 中看到的那样:

  

在我们的时候定义_Bool,bool,true和false宏   在GNU兼容的C ++方言中。修复&lt; rdar:// problem / 8477819&gt;。

所以gcc支持此作为扩展,并且进行了此修改以支持该扩展。

虽然我找不到补丁中提到的原始问题报告。

这是不符合的,我们可以从草案C ++ 11标准部分18.10中看到其他运行时支持 [support.runtime]

  

标题&lt; cstdbool&gt;和标题&lt; stdbool.h&gt;最好不要   定义名为bool,true或false的宏。

gcc并不意味着在GNU模式下严格遵守。

stdbool.h是C99的一部分,所以C ++标准不支持,直到 Annex D 中的C ++ 11:

  

为了与C标准库和C Unicode TR兼容,   C ++标准库提供25个C头,如表所示   154

并包含<stdbool.h>