When I for instance write 7>1
in C (say C99 if this is not an always-been feature), can I expect the result will be exactly 1 or just some non-zero value? D
All C operators that yield logically true/false values always yield a result of type int
with the value 0
for false, 1
for true.
That's not the case for all C expressions that yield logically true/false values. For example, the is*()
character classification functions declared in <ctype.h>
(isdigit()
, isupper()
, etc.) return 0
if the condition is false, but may return any non-zero value if the condition is true.
As long as you use the result directly as a condition:
if (isdigit(c)) ...
if (!isdigit(c)) ...
if (isdigit(c) || islower(c)) ...
and don't attempt to compare it to something:
if (isdigit(c) == 1) ... /* WRONG */
if (isdigit(c) == true) ... /* ALSO WRONG */
this shouldn't cause any problems.
(You can safely compare the result to 0
or false
, but there's no good reason to do so; that's what the !
operator is for.)
In C99 §6.5.8 Relational Operators, item 6 (<
,>
,<=
and >=
):
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) The result has type int.
As for equality operators, it's a bit further in §6.5.9 (==
and !=
):
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. The result has type int. For any pair of operands, exactly one of the relations is true.
The logical AND and logical OR are yet a bit further in §6.5.13 (&&
)
The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
... and §6.5.14 (||
)
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
And the semantics of the unary arithmetic operator !
are over at §6.5.3.3/4:
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. The result has type int. The expression !E is equivalent to (0==E).
Result type is int
across the board, with 0
and 1
as possible values. (Unless I missed some.)
C follows Postel's Law for its boolean operators: be conservative in what you do, be liberal in what you accept from others. It will treat any non-zero value as true in boolean expressions, but it will always produce either a 0 or a 1 itself. 2 != 3
is always 1
.
From the ISO C99 standard, section 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. The result has type int.
From section 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. The result has type int. For any pair of operands, exactly one of the relations is true.
Same thing happens with the logical conjunction (&&
) and disjunction (||
) operators.
PS: Incidentally, this is why the bitwise operators (&
and |
) can usually be used as non-short-circuiting versions of the logical operators.