无法将指针隐式转换为 _Bool 是编译器缺陷吗?
Is failure to implicitly convert a pointer to _Bool a compiler deficiency?
的答案表明标量可以转换为 _Bool
,并且 _Bool
的结果整数值将是 0
或 1
.
的公认答案指出指针是标量。
是否无法将指针隐式转换为 _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
$
请注意,只有隐式转换,而不是强制转换(显式转换),被问题编译器标记为错误。
另外,请注意,根据对 的评论,指出的问题编译器是旧的 - 从 2001 年开始 - 这可能与这是否是真正的编译器错误有关。 (我无法控制的原因阻止了所指出的问题交叉编译器的版本升级)
是的,这是一个编译器错误。虽然 C 在整数类型和指针类型之间没有任何方向的隐式转换,也没有指针类型之间的隐式转换,但特殊情况除外,例如 to/from pointer-to-void 或从 pointer-to-unqualified 到 pointer-to-qualified ,它确实定义了到 _Bool
的隐式转换。 (传统上许多编译器在其他地方支持这种隐式转换,但这样做是有害的,不是C语言的一部分。)
关于隐式转换的语言在6.5.16.1 Simple assignment:
One of the following shall hold:
- the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
- the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
- the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
- the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.
在标准中其他出现隐式转换的地方,都指定了"as if by assignment",参考上文。例如6.5.2.2中函数调用:
If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, ...
请注意,您的问题实际上是关于 初始化,这不是 C 语言中的赋值,而是一些不同的东西。但是,6.7.9 初始化 ¶11 涵盖了它:
The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply, taking the type of the scalar to be the unqualified version of its declared type.
_Bool
,并且 _Bool
的结果整数值将是 0
或 1
.
是否无法将指针隐式转换为 _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
$
请注意,只有隐式转换,而不是强制转换(显式转换),被问题编译器标记为错误。
另外,请注意,根据对
是的,这是一个编译器错误。虽然 C 在整数类型和指针类型之间没有任何方向的隐式转换,也没有指针类型之间的隐式转换,但特殊情况除外,例如 to/from pointer-to-void 或从 pointer-to-unqualified 到 pointer-to-qualified ,它确实定义了到 _Bool
的隐式转换。 (传统上许多编译器在其他地方支持这种隐式转换,但这样做是有害的,不是C语言的一部分。)
关于隐式转换的语言在6.5.16.1 Simple assignment:
One of the following shall hold:
- the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
- the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
- the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
- the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.
在标准中其他出现隐式转换的地方,都指定了"as if by assignment",参考上文。例如6.5.2.2中函数调用:
If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, ...
请注意,您的问题实际上是关于 初始化,这不是 C 语言中的赋值,而是一些不同的东西。但是,6.7.9 初始化 ¶11 涵盖了它:
The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply, taking the type of the scalar to be the unqualified version of its declared type.