doubles used as booleans
Guy Harris
guy at auspex.auspex.com
Fri Mar 31 17:44:37 AEST 1989
> The optimizing in the compilers I was using was minimal, and I
> found that substitutions such as 'if(i)' instead of 'if(i != 0)',
> and 'if(!n)' in place of 'if(n == 0)' produced smaller code for
> integral types. When I tried to extend this technique to floating
> types where the potential gains were even greater (floating point
> comparisons were expensively implemented), the code broke completely.
Proof positive that lack of memory sometimes produces
less-than-wonderful compilers - I would hope any *modern* non-toy
compiler would not give you any better code for "if (i)" than it gives
for "if (i != 0)".
> Pray, what sayeth the pANS?
3.1.2.5 Types
...
Integral and floating types are collectively called
"arithmetic types". Arithmetic types and pointer types are
collectively called "scalar types".
3.2.1.5 Usual arithmetic conversions
Many binary operators that expect operands of arithmetic
type cause conversions and yield result types in a similar way.
... This pattern is called the "usual arithmetic conversions":
First, if either operand has type "long double", the
other operand is converted to "long double".
Otherwise, if either operand has type "double", the
other operand is converted to "double".
Otherwise, if either operand has type "float", the other
operand is converted to "float".
3.3.8 Relational operators
...
Semantics
If both of the operands have arithmetic type, the usual
arithmetic conversions are performed.
3.3.9 Equality operators
...
Semantics
The == (equal to) and the != (not equal to) operators are
analogous to the relational operators except for their lower
precedence. Where the operands have types and values suitable
for the relational operators, the semantics detailed in section
3.3.8 apply.
3.3.3.3 Unary arithmetic operators
Constraints
The operand ... of the ! opearator (shall have) scalar
type.
Semantics
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)".
3.3.13 Logical AND operator
Constraints
Each of the operands shall have scalar type.
Semantics
The && operator shall yield 1 if both of its operands
compare unequal to 0, otherwise it yields 0. The result has
type "int".
3.3.14 Logical OR operator
(same thing, only it yields 1 if *either* of its operands
compare unequal to 0)
3.3.15 Conditional operator
Constraints
The first operand shall have scalar type.
...
Semantics
The first operand is evalueate; there is a sequence point
after its evaluation. The second operand is evaluated only if
the first operand compares unequal to 0; the third operand is
evaluated only if the first compares equal to 0; the value of
the second or third operand (whichever is evaluated) is the
result.
3.6.4.1 The "if" statement
Constraints
The controlling expression of an "if" statement shall have
scalar type.
Semantics
In both forms, the first substatement is executed if the
expression compares unequal to 0.
When you combine all that stuff, it dictates, among other things, that
double d;
if (d)
had better be equivalent to
double d;
if (d != 0.0)
or
if (d != 0)
given that the "0" in the latter case is converted to "0.0", and that
double a, b;
.
.
if ( a && b ) /* meaning if(a != 0.0 && b != 0.0) */
statement;
had better be interpreted precisely the way you state it.
> If it means anything, doubles were implemented as IEEE 754
> 64-bit reals, where 0.0 was represented by a zero-bit pattern.
> Maybe that's the only reason the latter cases worked! :-)
One hopes that if there ever were compilers dumb enough to think that
the "if" statement worked by testing whether the all the bits of the
value in the parentheses were zero, those compilers are now toast and
their authors have repented of their errors.
More information about the Comp.lang.c
mailing list