由于任何非零值都表示为真,但是>
、<
、==
等运算符返回1
表示真,我想知道是否有任何重要的C编译器在这些运算符可以产生大于1
的值。
换句话说,是否有任何编译器在执行 int i = (a == b)
; 这个语句时,如果我打算将 i
用作整数而不是布尔值,并假设它将是0
或1
,则会导致未定义的行为?
由于任何非零值都表示为真,但是>
、<
、==
等运算符返回1
表示真,我想知道是否有任何重要的C编译器在这些运算符可以产生大于1
的值。
换句话说,是否有任何编译器在执行 int i = (a == b)
; 这个语句时,如果我打算将 i
用作整数而不是布尔值,并假设它将是0
或1
,则会导致未定义的行为?
不会,如果有的话,它们不是C编译器:) C语言规定关系和相等运算符返回1表示真,0表示假。
C语言对将整数值解释为布尔值的规则是,0
表示假,任何其他值表示真。请参见处理 if / while / do / for
的C11部分,其中所有内容都包含类似于"while表达式与零不相等"
的语言。具体地:
6.8.4.1/2:在两种形式[if语句的一种有else子句,一种没有]中,如果表达式与0不相等,则执行第一个子语句。在else形式中,如果表达式比较等于0,则执行第二个子语句。
6.8.5/4:迭代语句[while、do和for]导致称为循环主体的语句重复执行,直到控制表达式与0相等。
然而,针对比较类型的表达式,你将得到什么结果就非常明确了,你要么得到0
,要么得到1
。这些方面的C11标准的相关部分全部都在6.5表达式
下:
6.5.8/6:<(小于)、>(大于)、<=(小于或等于)和> =(大于或等于)运算符中的每个运算符都应返回1,如果指定的关系为真,则返回0。
6.5.9/3:==(等于)和!=(不等于)运算符类似于关系运算符,除了它们的优先级较低之外。如果指定的关系为真,则每个运算符都返回1;如果指定的关系为假,则返回0。
6.5.13/3:&&运算符应返回1,如果它的两个操作数都与0不相等;否则,它将返回0。
6.5.14/3: ||
运算符应当在它的任意一个操作数与 0 不相等时返回 1;否则,返回 0。
6.5.3.3/5: !
运算符对于操作数值与 0 不相等时返回 0,如果操作数等于 0,则返回 1。
这种行为早在 C99 和 C89(ANSI 时代)就已经存在了。C99 中处理关系和等式运算符的章节也指出其返回值只能是 0 或 1。
C89 草案虽然没有明确规定等式运算符的返回值,但它确实说:
==(等于)和!=(不等于)运算符与关系运算符相似,只是它们的优先级较低。
而关系运算符一节确实说明:
<(小于)、>(大于)、<=(小于或等于)和>=(大于或等于)运算符应当在指定的关系为真时返回 1,为假时返回 0。
参考:http://flash-gordon.me.uk/ansi.c.txt,因为我没有任何 C89 标准的副本。我有第二版的 K&R(1988 年 ANSI 版本),它在附录 A 的第 7.9 和 7.10 节中基本上说明了同样的内容。如果您想要从第一版得出确定的答案,那就需要找一个妻子不太喜欢扔旧东西的人。
补充:
根据 Michael Burr 的说法,他要么没有结婚,要么他的妻子比我更愿意保留旧书 :-)
K&R第一版(1978年)在7.6和7.7中也是这样说的:“如果指定的关系为假,则所有[关系运算符]均产生0,如果为真,则产生1。” …“[等式运算符]与关系运算符完全类似,只是它们的优先级较低。”
a +=(b == c)
可能不是每天都会看到,但它们足够常见。它们在过去可能更加普遍。 - Michael Burr0
或1
。
参考资料:
C99标准:6.5.9 相等运算符
第3段:
==(等于)和!=(不等于)运算符类似于关系运算符,除了它们的优先级较低外。108)如果指定的关系为真,则每个运算符产生1,如果为假则产生0。结果的类型为int。对于任何一对操作数,只有一个关系为真。
0
或1
,编译器实现应遵守标准规定。 - Alok Save我认为这里的人们并没有回答问题。问题不是关于标准规定了什么,而是是否有任何著名的编译器在这方面不遵守标准。
据我所知,没有这样的编译器。
按照规范,为了被视为C语言,条件运算符必须返回0表示false,返回1表示true。
用俳句的形式表达:
条件成立, 回归1; 不成立, 安放0。Specification
Disallows this behavior,
Otherwise not C.
等于(==)和不等于(!=)运算符类似于关系运算符,除了它们具有更低的优先级。108)每个运算符如果指定的关系成立,则产生1;否则产生0。结果类型为int。对于任何一对操作数,只有一个关系是真的。
因此,
s/notable/<插入脏话>/g
:-) - paxdiablo?1:0
来进行“布尔化”,但我想知道我是否真的需要如此谨慎。 - vsz