C99 - 为什么假和真的定义为0和1而不是((bool)0)和((bool)1)?

Kai*_*udi 5 c boolean language-design c99

偶然发现了一个失败的断言,因为它将false与函数的返回类型进行了比较,因为函数本身返回了一个bool并且断言不仅检查了值,还检查了返回值的类型以匹配false,保证,返回一个bool.现在的问题是,C99将bool定义为_Bool,而_Bool甚至不一定与int相同(实际上,根据我的经验,在现今的大多数平台上它通常与unsigned char相同),不要谈论相同type(实际上这是不可能的,因为_Bool是C99中语言的内置类型),但是将false和true定义为0和1而没有任何类型转换和没有类型转换的预处理器定义将默认为int.如果C99改为将false和true定义为((bool)0)和((bool)1),则它们将始终为bool类型,无论如何定义_Bool.那么有没有什么好的理由让它们总是被定义为int,即使bool不是那个平台上的int,或者这只是语言中的一个bug,应该用C1x修复?

San*_*ker 8

false并且true被定义为整型常量01分别,因为这正是C99标准规定了部分7.16:

<SNIP>

其余三个宏适用于#if预处理指令.他们是

真正

它扩展为整数常量1,

它扩展为整数常量0,和

<SNIP>

编辑:正如下面的评论所示,似乎我略微误解了这个问题,我应该提供标准指定它的原因.其中一个原因,我能想到的,是truefalse应该是在使用#if预处理指令(从标准报价提到).

在预处理指令中起作用((bool) 0)((bool) 1)不起作用的原因#if是标准不允许它.在6.10.1节中,它说:

控制条件包含的表达式应为整数常量表达式,除了:它不应包含强制转换;

  • @Kaiserludi:明白了.我似乎误解了这个问题.我现在看到@Rob的含义.我想不使它们成为`_Bool`类型的原因是因为它们应该在`#if`预处理指令中可用,正如上面引用的引用. (2认同)

Ste*_*non 5

除了已经提到的其他原因之外,因为 a_Bool变成了int只要你用它做了几乎任何事情,

\n\n

例如, 的类型是什么(_Bool)0 & (_Bool)1?您可能认为表达式的类型为_Bool,但实际上 \xc2\xa76.5.10 定义了以下语义&

\n\n
\n

...通常的算术转换是在操作数上执行的...

\n
\n\n

“通常的算术转换”在 C 标准中具有非常具体的含义。它在\xc2\xa76.3.1.8中定义,并包括以下内容:

\n\n
\n

...对两个操作数都执行整数提升...

\n
\n\n

“整数促销”也是一个定义术语,来自 \xc2\xa76.3.1.1:

\n\n
\n

如果一个int可以表示原始类型的所有值,则将该值转换为int;否则,它被转换为无符号整型。这些称为整数提升。48) 所有其他类型都不会因整数提升而改变。

\n
\n\n

尽管比intC 标准中存在的类型更窄,但它们会自动扩展到int几乎任何表达式中。再加上布尔运算的结果具有类型这一事实int,这使得int这些文字的类型成为自然选择。

\n

  • @jamesdlin:如果您关心函数的副作用,您很可能关心调用两个函数的**顺序**。实际上,我曾经尝试做类似您建议的事情,当它出现时,它让我很伤心一个特定的编译器决定反转调用的顺序...我现在甚至可以说,使用具有副作用的多个函数作为算术/按位运算符的操作数几乎总是有害的。 (4认同)