C标准在哪里定义了两个布尔值相加/相减的结果?

4

C11标准定义了_Bool类型(6.2.5.2)为标准的无符号整数类型(6.2.5.6),并且根据标准,_Bool也是一种算术类型(通过6.2.5.7和6.2.5.17进一步确认,见6.2.5.18)。

此外,规定对于+-运算符,“两个操作数都必须是算术类型,或者一个操作数必须是指向完整对象类型的指针,另一个操作数必须是整数类型”(见6.5.6.2)。

然而,关于结果,我只能看到"The result of the binary + operator is the sum of the operands"(6.5.6.5)和"The result of the binary - operator is the difference resulting from the subtraction of the second operand from the first"(6.5.6.6)。对于两个布尔值,“sum”可以被解释为逻辑或,但我认为“subtraction”没有明确定义的含义。因此,问题是:在C11中,a+ba-b(其中ab具有类型_Bool)的结果是否为未定义行为,还是标准清晰地定义了这些操作的结果(如果是,哪里)?注意:也许标准只将_Bool视为非常小范围的整数。在这种情况下,我希望true+true等于0(1 + 1按模2计算)。然而,GCC says 1

我的理解是 _Bool 类型类似于 enum - Basile Starynkevitch
任何非 0False 的值都是 True。即使是 -1 也是 True - Tauqeer Akhtar
1
由于bool类型比int类型更小,应该将其提升为int类型,因此你得到了“1 + 1 = 2”——然后你再次将其分配给bool类型,尽管对于转换而言,它应该像“!=0”一样运作。 - Aconcagua
1个回答

4

根据C标准(6.5.6加法运算符), 当两个操作数都具有算术类型时,会对它们进行通常的算术转换(usual arithmetic conversions)。

同时根据(6.3.1.8 通常的算术转换), 许多需要算术类型的操作符以类似的方式执行转换并产生结果类型...

否则,将对两个操作数执行整数提升(integer promotions)

此外,根据(6.3.1.1 布尔、字符和整型), 如果int类型可以表示原始类型(对于位域来说受到宽度的限制),则将值转换为int; 否则将其转换为unsigned int。这被称为整数提升,所有其他类型均不受此影响。

因此,在两个操作数均为类型为_Bool且在执行操作之前被整数提升为类型int的情况下,加法运算的结果类型为int

请注意,在C语言中没有像C++中那样的布尔类型,布尔类型_Bool是C语言中的标准无符号整数类型,可以存储10

因此,如果您写:

_Bool a = 1;
_Bool b = 1;
_Bool c = a + b;

变量c的值将为1,因为任何非零值(操作的结果为类型为int的值2)都会转换为1。

来源于C标准

6.3.1.2布尔类型

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


谢谢。隐式提升为 int 是我缺失的链接。走向极端情况,这意味着在同一表达式中多次添加 1 (_Bool) 直到 int 溢出是未定义行为。虽然很难想象它有任何实际重要性。无论如何,加法和减法的结果都是直观的(加法是逻辑 OR,减法给出“true”如果操作数之间存在差异)。 - nielsen
@nielsen 完全不用谢。:) - Vlad from Moscow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接