问题
As anything non-zero means true, but the >
, <
, ==
etc. operators returning 1
for true, I'm curious if there are any notable C compilers where these operators can result in a value greater than 1
.
In other words, is there any compiler where int i = (a==b)
; would result in undefined behavior if I intended to use i
not as a boolean value, but as an integer, and was assuming it would be either 0
or 1
?
回答1:
No, if there are, they're not C compilers :-) The standard mandates that relational and equality operators return 1 for true and 0 for false.
The rule for interpretation of integral values as boolean values by C states that 0
is false and any other value is true. See C11 sections dealing with if/while/do/for
, which all contain language like "while the expression compares unequal to zero"
. Specifically:
6.8.4.1/2: In both forms [of the if statement, one with and one without an else clause], the first substatement is executed if the expression compares unequal to 0. In the else form, the second substatement is executed if the expression compares equal to 0.
6.8.5/4: An iteration statement [while, do and for] causes a statement called the loop body to be executed repeatedly until the controlling expression compares equal to 0.
However, it's quite explicit what result you will get for the comparison-type expressions, you either get 0
or 1
. The relevant bits of the C11 standard for these are all under 6.5 Expressions
:
6.5.8/6: Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.
6.5.9/3: The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence. Each of the operators yields 1 if the specified relation is true and 0 if it is false.
6.5.13/3: The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0.
6.5.14/3: The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0.
6.5.3.3/5: The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0.
And this behaviour goes way back to C99 and C89 (ANSI days). The C99 sections dealing with relational and equality operators also states that the return values is either 0 or 1.
And, while the C89 draft doesn't explicitly dictate the return values for equality operators, it does say:
The == (equal to) and the != (not equal to) operators are analogous to the relational operators except for their lower precedence.
And the relational operators section does state:
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.
Reference: http://flash-gordon.me.uk/ansi.c.txt since I don't have any copies of the C89 standards floating around. I do have the second edition of K&R (the ANSI one from 1988) which basically says the same thing, in sections A7.9 and A7.10 of Appendix A, the Reference Manual. If you want a definitive answer from the first edition, that'll have to come from someone with a wife less prone to throwing out old junk.
Addendum:
According to Michael Burr, who is either not married or has a more accommodating wife than I in terms of keeping old books :-)
K&R 1st Edition (1978) also says the same in 7.6 and 7.7: "The [relational operators] all yield 0 if the specified relation is false and 1 if it is true." ... "The [equality operators] are exactly analogous to the relational operators except for their lower precedence."
回答2:
They are guaranteed to return 0
or 1
.
Reference:
C99 Standard: 6.5.9 Equality operators
Para 3:
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
回答3:
I don't think people here are answering the question. Question was not about what the standard says, the question was about if there are any notable compilers out there that do not obey the standard in that regard.
No, as far as I know, there are not.
回答4:
I don't have access to the C standard, but according to Wikipedia:
C uses an integer type, where relational expressions like i > j and logical expressions connected by && and || are defined to have value 1 if true and 0 if false, whereas the test parts of if, while, for, etc., treat any non-zero value as true.
Wikipedia luckily does have the correct citations, but as they're references to books, not sure how much help that is :).
回答5:
As far as i can find is this from 6.5.9 paragraph 3 in C99 standard
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
Therefore it seems that the evaluated values should be either 1 or 0
回答6:
By specification, to be considered the C language, the conditional operators must return 0 for false and 1 for true.
In haiku form:
Specification
Disallows this behavior,
Otherwise not C.
回答7:
Before c89/c90/ANSI-C, the compare operators were guaranteed to produce a zero value on a "false" condition, and not-equal-to-zero otherwise. The substitute 1 for true "standardisation" that was introduced by c89 is seldomly needed, and in cases where is is needed, one could use a = (b==c) ? 1 : 0;
.
来源:https://stackoverflow.com/questions/10632237/any-c-compiler-where-evaluates-to-larger-than-one