【问题标题】:Is (bool) cast reliably 0 or 1? [duplicate](bool) 是否可靠地转换为 0 或 1? [复制]
【发布时间】:2020-03-12 04:25:08
【问题描述】:

从一些readingonStack Overflow,我推测bool,定义在stdbool.h,是一个扩展为内置类型_Bool的宏,而true是定义为1false 定义为0

转换为bool 是否保证返回01 的值? _Bool 变量(包括转换右值)可能会获得 0 或 1 以外的值吗?

以下代码暗示 _Bool 变量,包括转换右值,将只有 01 的值,但我想确认这是有保证的,而且我没有观察目标- 或编译器版本特定的行为。

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

$ 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

【问题讨论】:

  • @AlexLop。 - 确实如此,谢谢。我以为我尽职尽责地寻找相关的现有帖子,但我想答案就在那里。仍然感谢现有的答案。

标签: c boolean stdbool


【解决方案1】:

C 2018 6.3.1.2 1 说:

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

【讨论】:

  • 我想我意识到了一个有趣的极端案例:我记得很久以前就知道虽然NULL 几乎肯定是0,但它并不能保证。在这种情况下,(bool)NULL 将评估为1,并且只有非NULL 指针0x0 在转换为0 时评估为0
  • @StoneThrow:如果一个指针是一个空指针,包括NULL,它比较等于0,不管C实现如何表示一个空指针。
  • @StoneThrow:这是错误的。转换为bool的结果是0还是1与空指针如何表示无关。如果指针为空则为 0,如果指针不为空则为 1。
  • @StoneThrow "(bool)NULL 将评估为 1" 是可能的(当 NULL 是某个非零整数时)。 (bool)non_null_pointer 的计算结果始终为 1 - 无论 NULL 是如何定义的。
  • @chux-ReinstateMonica: (bool) NULL 始终为 0,除非 boolNULL 的定义不是标准头文件中提供的。 NULL 是 0 或 0 转换为 void *。比较 0 和 0 的结果为真。将转换为void * 的 0 与 0 进行比较的结果为 true,无论它是如何表示的。因此,到 6.3.1.2 1,(bool) NULL 的计算结果为 0。
【解决方案2】:

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

【讨论】:

  • 这是一个相当广泛的免责声明。它适用于任何事情。 * 相乘,除非有未定义的行为导致它。 printf 打印,除非有未定义的行为导致它。...
  • @EricPostpischil:确实,但我觉得需要在这里说一下,因为该语言的许多用户并没有真正理解未定义的 UB 是如何,并且从如果您还没有对 UB 的直觉,那么“不能有其他值”的对象真的很令人惊讶。
猜你喜欢
  • 1970-01-01
  • 2011-05-15
  • 2019-08-29
  • 2011-12-16
  • 2018-10-09
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
相关资源
最近更新 更多