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