回答this question状态,可以将标量转换为_Bool
,并且_Bool
的所得整数值为0
或1
。
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在整数类型和指针类型之间没有任何方向的隐式转换,也没有指针类型之间的隐式转换,除非在特殊情况下(例如,从指针到无效或从指针到不合格到指针到合格),它确实定义了对_Bool
的隐式转换。 (传统上,许多编译器在其他地方都支持这种隐式转换,但是这样做是有害的,并且不是C语言的一部分。)
有关隐式转换的语言在6.5.16.1 Simple assignment下:
具有下列条件之一:
- 左操作数具有原子,限定或不限定的算术类型,而右具有算术类型;
- 左操作数具有与右类型兼容的结构或联合类型的原子,合格或不合格版本;
- 左操作数具有原子,限定或不限定的指针类型,并且(考虑到左操作数在左值转换后将具有的类型),两个操作数都是指向兼容类型的限定或不限定版本的指针,并且该类型由左侧指向具有右侧所指类型的所有限定符;
- 左操作数具有原子,限定或不限定的指针类型,并且(考虑到左操作数在左值转换后将具有的类型),一个操作数是指向对象类型的指针,而另一个是指向限定或不限定类型的指针。 void的版本,并且左侧指向的类型具有右侧指向的类型的所有限定符;
- 左操作数是原子,限定或不限定的指针,而右是空指针常量;或
- 左操作数的类型是atomic,合格或不合格的_Bool,而右边是指针。
在标准中隐式转换出现的其他位置,请参阅上文,将其指定为“好像是通过赋值”。例如,在6.5.2.2中,函数调用:
如果表示被调用函数的表达式的类型确实包含原型,则参数将隐式转换,就像通过赋值一样,...
请注意,您的问题实际上是关于初始化的问题,它不是C语言中的赋值,而是一些不同的东西。但是,6.7.9初始化¶11涵盖了它:
标量的初始值设定项应为单个表达式,可以选择用大括号括起来。对象的初始值是表达式的初始值(转换后); 使用与简单赋值相同的类型约束和转换,将标量的类型作为其声明类型的非限定版本。