考虑代码:
int foo(void)
{
_Bool b = 1; // is true
int i = 42; // mean true in conditions
if (i == b)
return 1;
else if ((_Bool)i == b)
return 2;
else
return 3;
}
根据C标准(C99或C11),此功能将返回什么?
P.S。在带有-std=c99
选项的GCC 4.7.2上,该函数返回2。
答案 0 :(得分:2)
返回2
。
“通常的算术转换”应用于==
运算符的操作数。 _Bool
是一种无符号类型,其转化排名低于int
或unsigned int
。
“通常的算术转换”在C99或C11标准的第6.3.1.8节“常用算术转换”中指定(链接是最近的草稿)。
在i == b
中,由于没有浮点操作数,“整数提升”将应用于两个操作数,将正确的操作数从_Bool
提升为int
并产生值1
。现在两个操作数都是相同的类型,因此不需要进一步的转换。因此i == b
相当于42 == 1
,这是假的。
在(_Bool)i == b
中,“整数促销”仍然适用于两个操作数,因此两者都从_Bool
转换为int
。 (从int
到_Bool
并返回int
的转换会丢失信息,将所有非零值转换为1
。)现在两个操作数的类型相同,所以无需进一步转换。因此(_Bool)i == b
相当于1 == 1
,这是真的 - 函数返回2
。
(注意:由于我在阅读标准时有些粗心,这是关于这个答案的第三个主要编辑。我想这次我做对了。)
在回答评论中的问题时,b == 42u
将b
从_Bool
提升为int
,从而产生int
与unsigned int
比较。由于操作数具有不同的符号但具有相同的转换等级,因此带符号的操作数将转换为无符号类型。将1
从int
转换为unsigned int
是微不足道的,产生1u
。因此,比较等同于1u == 42u
,这是假的。
(请注意,与其他相等和关系运算符一样,C中的==
运算符会生成类型为int
的结果,其值为0
或1
,< em> not 类型_Bool
的结果。)
答案 1 :(得分:0)
如果两个操作数都有算术类型,则通常的算术转换是 进行。
因此,在评估表达式i == b
时,将发生算术转换。在算术转换期间,所有涉及的操作数都将转换为所有可以“适合”的最低排序类型,在本例中为int
。
自1 != 42
以来,第一个条件不成立。
第二个表达式首先将i
投射到_Bool
,结果为true
。然后它评估true == true
,显然是true
。因此该函数返回2
。
答案 2 :(得分:0)
为什么不运行它?
实际上是返回2
。带有-std=gnu99