We know that any numbers that are not equal to 0
are viewed as true
in C, so we can write:
int a = 16;
while (a--)
printf(\"%d
Does the C standard explicitly indicate the truth values of
true
andfalse
as0
and1
respectively?
The C standard defines true
and false
as macros in stdbool.h
which expand to 1
and 0
respectively.
C11-§7.18:
The remaining three macros are suitable for use in
#if
preprocessing directives. They aretrue
which expands to the integer constant
1
,false
which expands to the integer constant
0
[...]
For the operators ==
and !=
, standard says
C11-§6.5.9/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 yields1
if the specified relation is true and0
if it is false. The result has typeint
. For any pair of operands, exactly one of the relations is true.
It happened because of the Relational Operators in your printf
statement.
Operator ==
and operator !=
Since (0 == 0)
holds true so, it gives a value 1
whereas, (0 != 0)
doesn't hold true so, gives a value 0
.
This answer needs to be looked at a bit more closely.
The actual definition in C++ is that anything not 0 is treated as true. Why is this relevant? Because C++ doesn't know what an integer is by how we think about it--we create that meaning, all it holds is the shell and rules for what that means. It knows what bits are though, that which make up an integer.
1 as an integer is loosely represented in bits, say an 8-bit signed int as 0000 0001. Many times what we see visually is a bit of a lie, -1 is a much more common way to represent it because of the signed nature of 'integer'. 1 really can't mean true proper, why? Because it's NOT operation is 1111 1110. That's a really major issue for a boolean. When we talk about a boolean, it's just 1 bit--it's really simple, 0 is false and 1 is true. All the logic operations hold as trivial. This is why '-1' should be designated as 'true' for integers (signed). 1111 1111 NOT'ed becomes 0000 0000---the logic holds and we're good. Unsigned ints is a little bit tricky and were a lot more commonly used in the past--where 1 means true because it's easy to imply the logic that 'anything not 0 is true'.
That's the explanation. I say the accepted answer here is wrong--there is no clear definition in the C/C++ definition. A boolean is a boolean, you can treat an integer as a boolean, but the fact the output is an integer says nothing about the operation actually being done is bitwise.
I've programmed in many languages. I've seen true be 1 or -1 depending on the language. The logic behind true being 1 was that a bit was either a 0 or 1. The logic behind true being -1 was that the ! operator was a one's complement. It changed all the 1's to 0's and all the 0's to 1's in an int. So, for an int, !0 = -1 and !(-1) = 0. This has tripped me up enough that I don't compare something to be == true, but instead compare it to be != false. That way, my programming style works in every language. So my answer is to not worry about it, but program so that your code works correctly either way.
There are two areas of the standard you need to be aware with when dealing with Boolean values (by which I mean true/false values rather than the specific C bool/_Bool
type) in C.
The first has to do with the result of expressions and can be found in various portions of C11 6.5 Expressions
(relational and equality operators, for example) . The bottom line is that, whenever a Boolean value is generated by an expression, it ...
... yields 1 if the specified relation is true and 0 if it is false. The result has type int.
So, yes, the result of any Boolean-generating expression will be one for true, or zero for false. This matches what you will find in stdbool.h
where the standard macros true
and false
are defined the same way.
Keep in mind however that, following the robustness principle of "be conservative in what you send, liberal in what you accept", the interpretation of integers in the Boolean context is somewhat more relaxed.
Again, from various parts of 6.5
, you'll see language like:
The
||
operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
From that (and other parts), it's obvious that zero is considered false and any other value is true.
As an aside, the language specifying what value are used for Boolean generation and interpretation also appear back in C99 and C89 so they've been around for quite some time. Even K&R (ANSI-C second edition and the first edition) specified that, with text segments such as:
Relational expressions like
i > j
and logical expressions connected by&&
and||
are defined to have value1
if true, and0
if false.In the test part of
if
,while
,for
, etc, "true" just means "non-zero".The
&&
operator ... returns 1 if both its operands compare unequal to zero, 0 otherwise.The
||
operator ... returns 1 if either its operands compare unequal to zero, and 0 otherwise.
The macros in stdbool.h
appear back in C99 as well, but not in C89 or K&R since that header file did not exist at that point.
It is not explicitly indicated in C11. All language-level operations will return 1 as truthy (and accept any nonzero including NaN as true).
_Bool
, then true must be 1 because the standard only require it to hold 0 and 1. (§6.2.5/2). <stdbool.h>
the macro true
expands to 1
(§7.18/3)==
, !=
, <
, >
, <=
and >=
return 0 or 1 (§6.5.8/6, §6.5.9/3).!
, &&
and ||
return 0 or 1 (§6.5.3.3/5, §6.5.13/3, §6.5.14/3)defined
expands to 0 or 1 (§6.10.1/1)But all standard library functions e.g. islower
just say "nonzero" for truthy (e.g. §7.4.1/1, §7.17.5.1/3, §7.30.2.1/1, §7.30.2.2.1/4).
§6.2.5/2: An object declared as type
_Bool
is large enough to store the values 0 and 1.§6.5.5.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. …§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.107) …§6.5.9/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. …§6.5.13/3: The
&&
operator shall yield 1 if both of its operands compare unequal to 0; …§6.5.14/3: The
||
operator shall yield 1 if either of its operands compare unequal to 0; …§6.10.1/1: … it may contain unary operator expressions of the form —
defined identifier
— or —defined ( identifier )
— which evaluate to 1 if …§7.4.1 (Character classification functions)/1: The functions in this subclause return nonzero (true) if and only if …
§7.18/3: The remaining three macros are suitable for use in
#if
preprocessing directives. They are —true
— which expands to the integer constant 1, …§7.17.5.1/3: The
atomic_is_lock_free
generic function returns nonzero (true) if and only if the object’s operations are lock-free. …§7.30.2.1 (Wide character classification functions)/1: The functions in this subclause return nonzero (true) if and only if …
§7.30.2.2.1/4: The
iswctype
function returns nonzero (true) if and only if …