You are mixing up a lot of different things: control statements, operators and boolean types. Each have their own rules.
Control statements work like for example the if
statement, C11 6.4.8.1:
In both forms, the first substatement is executed if the expression
compares unequal to 0.
while
, for
etc have the same rule. This has nothing to do with "true" or "false".
As for operators that are supposedly yielding a boolean result, they are actually yielding an int
with value 1 or 0. For example the equality operators, C11 6.5.9:
Each of the operators yields 1 if the specified relation is true and 0
if it is false
All of the above is because C did not have a boolean type until the year 1999, and even when it did get one, the above rules weren't changed. So unlike most other programming languages where statements and operators yield a boolean type (like C++ and Java), they just yield an int
, with a value zero or not zero. For example, sizeof(1==1)
will give 4 in C but 1 in C++.
The actual boolean type in C is named _Bool
and requires a modern compiler. The header stdbool.h
defines macros bool
, true
and false
, that expand to _Bool
, 1
and 0
respectively (for compatibility with C++).
It is however considered good programming practice to treat control statements and operators as if they actually required/yielded a boolean type. Certain coding standards like MISRA-C recommend such practice. That is:
if(ptr == NULL)
instead of if(ptr)
.
if((data & mask) != 0)
instead of if(data & mask)
.
The aim of such style is to increase type safety with the aid of static analysis tools, which in turn reduces bugs. Arguably, this style is only meaningful if you do use static analysers. Though in some cases it leads to more readable, self-documenting code, for example
if(c == '\0')
Good, the intent is clear, the code is self-documenting.
versus
if(c)
Bad. Could mean anything, and we have to go look for the type of c
to understand the code. Is it an integer, a pointer or a character?