4

从Stack Overflow上的一些阅读 中,我了解到,正如 中所定义的那样,它是一个扩展为内置类型的宏,它被定义为并被定义为. boolstdbool.h_Booltrue1false0

强制转换是否bool保证返回值0or 1?一个_Bool变量(包括强制转换右值)是否可能获得 0 或 1 以外的值?

以下代码暗示_Bool变量(包括强制转换右值)将仅具有0or的值1,但我想确认这是有保证的,并且我没有观察目标或编译器版本特定的行为。

(FWIW,我最感兴趣的是确认只有NULL, 转换为_Bool, 将是0, 并且所有其他可能的指针值, 转换为_Bool, 将是1)

$ cat ./main.c
#include <stdio.h>
#include <stdbool.h>

int main( int argc, char* argv )
{
  int   i;
  int*  p = &i;
  int*  n = NULL;

  printf( "%zu\n", sizeof( (bool)p ) );
  printf( "%p - %d\n", p, (bool)p );
  printf( "%p - %d\n", n, (bool)n );
  printf( "%d\n", (bool)3 );

  return 0;
}
$ gcc --version
gcc (GCC) 8.2.1 20181215 (Red Hat 8.2.1-6)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -g ./main.c && ./a.out    
1
0x7ffdac3290bc - 1
(nil) - 0
1
4

2 回答 2

2

C 2018 6.3.1.2 1 说:

当任何标量值转换为 时_Bool,如果该值比较等于 0,则结​​果为 0;否则,结果为 1。

于 2019-11-16T01:54:44.190 回答
2

是的,强制转换bool保证会导致 0 或 1,直到未定义的行为可以产生任何东西的限制。如果有未定义的行为导致转换bool发生的路径,那么您可能会观察到奇怪的事情,因为编译器可能已经根据不再有效的假设正确地进行了转换。例如,如果实现在存储时执行折叠到 0/1,它可能会在bool从内存加载时假设值已经是 0 或 1,并且不需要进一步折叠。如果bool对象的存储已通过缓冲区溢出、别名违规等进行了更改,那么最终可能会看到不同的值。

于 2019-11-16T01:56:38.210 回答