是否无法将指针隐式转换为_Bool编译器缺陷?

问题描述 投票:2回答:1

回答this question状态,可以将标量转换为_Bool,并且_Bool的所得整数值为01

this question的公认答案指出指针是标量。

是否无法将指针隐式转换为_Bool,因此是编译器错误?

例如:

$ cat ./main.c 
// main.c

#include <stdbool.h>

int main( int argc, char* argv )
{
  int  i;
  int* p   = &i;
  bool foo = (bool)p;
  bool bar = p;

  return 0;
}

失败的编译器(之一):

$ /path/to/mips_fp_le-gcc --version
2.95.3
$ /path/to/mips_fp_le-gcc ./main.c 
./main.c: In function `main':
./main.c:10: incompatible types in initialization

正在传递的编译器(很多):

$ gcc --version
gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)
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 ./main.c 
$ 

请注意,问题编译器仅将隐式转换而不是强制转换(显式转换)标记为错误。另外,请注意,根据对this question的评论,指出的问题编译器很旧-从2001年开始-可能与这是否是真正的编译器错误有关。 (我无法控制的原因导致交叉编译器无法升级该版本的问题)

c casting implicit-conversion stdbool
1个回答
1
投票

是的,这是一个编译器错误。尽管C在整数类型和指针类型之间没有任何方向的隐式转换,也没有指针类型之间的隐式转换,除非在特殊情况下(例如,从指针到无效或从指针到不合格到指针到合格),它确实定义了对_Bool的隐式转换。 (传统上,许多编译器在其他地方都支持这种隐式转换,但是这样做是有害的,并且不是C语言的一部分。)

有关隐式转换的语言在6.5.16.1 Simple assignment下:

具有下列条件之一:

  • 左操作数具有原子,限定或不限定的算术类型,而右具有算术类型;
  • 左操作数具有与右类型兼容的结构或联合类型的原子,合格或不合格版本;
  • 左操作数具有原子,限定或不限定的指针类型,并且(考虑到左操作数在左值转换后将具有的类型),两个操作数都是指向兼容类型的限定或不限定版本的指针,并且该类型由左侧指向具有右侧所指类型的所有限定符;
  • 左操作数具有原子,限定或不限定的指针类型,并且(考虑到左操作数在左值转换后将具有的类型),一个操作数是指向对象类型的指针,而另一个是指向限定或不限定类型的指针。 void的版本,并且左侧指向的类型具有右侧指向的类型的所有限定符;
  • 左操作数是原子,限定或不限定的指针,而右是空指针常量;或
  • 左操作数的类型是atomic,合格或不合格的_Bool,而右边是指针。

在标准中隐式转换出现的其他位置,请参阅上文,将其指定为“好像是通过赋值”。例如,在6.5.2.2中,函数调用:

如果表示被调用函数的表达式的类型确实包含原型,则参数将隐式转换,就像通过赋值一样,...

请注意,您的问题实际上是关于初始化的问题,它不是C语言中的赋值,而是一些不同的东西。但是,6.7.9初始化¶11涵盖了它:

标量的初始值设定项应为单个表达式,可以选择用大括号括起来。对象的初始值是表达式的初始值(转换后); 使用与简单赋值相同的类型约束和转换,将标量的类型作为其声明类型的非限定版本。

© www.soinside.com 2019 - 2024. All rights reserved.