转换为_Bool

Casting to _Bool

传统上,C 中的布尔值用intchar 表示。新的 _Bool 类型使意图更清晰,但还有另一个有趣的特性:它似乎将浮点数转换为它,不会截断为零,而是与精确的零进行比较:

#include <stdio.h>

int main(int argc, char **argv) {
  double a = 0.1;
  int i = (int)a;
  printf("%d\n", i);
  _Bool b = (_Bool)a;
  printf("%d\n", b);
  return 0;
}

打印

0
1

所以这是语义上的差异。还有一个我很满意;它复制了使用浮点数作为条件的效果。

这是可以一刀切依赖的东西吗?新的 C 标准是否将 X 转换为 _Bool 的结果定义为与对所有 X 有效操作的 X ? 1 : 0 相同?

在C标准(6.3.1.2布尔类型)中写着

1 When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.

也就是说,在转换为类型 _Bool 期间,编译器不会尝试将具有转换运算符的表达式的操作数的值(截断为零或其他值)表示为整数。它只检查值是否等于或不等于零。

实际上是这个声明

 _Bool b = (_Bool)a;

等同于

 _Bool b = a;

完全一致,一个非零值隐式转换为_Booltrue。由于 _Bool 是真正的布尔类型而不是“伪造的”,因此它可以正常运行。所以:

_Bool b = (_Bool)a ;

相当于:

_Bool b = (a == 0) ;

不是:

_Bool b = ((int)a == 0) ;

最后,将浮点数解释为布尔值是无稽之谈,也是不明智的,因为比较它是否等于零也是如此。如果你想要你期望的语义,你必须显式编码:

_Bool b = (_Bool)((int)a);

语义上等同于:

_Bool b = (a < 1.0);

使用布尔表达式比强制转换为布尔值更清晰、更安全。