(bool) 是否可靠地转换为 0 或 1?
Is (bool) cast reliably 0 or 1?
从一些 reading on bool
,如 stdbool.h
中所定义,是一个扩展为内置类型 _Bool
的宏,并且true
定义为 1
,false
定义为 0
。
转换为 bool
是否保证 return 的值为 0
或 1
? _Bool
变量(包括强制转换的右值)可能会获得 0 或 1 以外的值吗?
以下代码暗示 _Bool
变量,包括强制转换右值,将只有 0
或 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
C 2018 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
保证会产生 0 或 1,直到未定义的行为可以产生任何东西的限制。如果存在导致转换为 bool
的路径的未定义行为,您可能会观察到奇怪的事情,因为编译器可能已根据不再有效的假设正确地进行了转换。例如,如果实现在存储时执行到 0/1 的折叠,它可能会假设从内存加载 bool
时该值已经是 0 或 1,并且不需要进一步折叠。如果 bool
对象的存储已通过缓冲区溢出、别名违规等方式更改,则最终可能会看到不同的值。