[net.lang.c] i = i * f *vs* i *= f

bet@ecsvax.UUCP (04/15/84)

What we have here is a type conversion problem. When i = i * f is evaulated,
the "i" on the right side of the assignment is promoted to float, the
expression is evaluated, and the result is converted back to integer for
the assignment. When i *= f is evaluated, the right side of the assignment
operator is evaluated, just as before: it is the float. It is then converted
to integer for the assignment operation: 0.2 goes to 0 in any reasonable
conversion. BEWARE incautious mixed types: they ALWAYS ALWAYS ALWAYS bite
back. C is perhaps as benign as any environment I know. Look at PL/I for
crissakes. If ANY numeric value gets converted to fixed decimal, you stand a
good chance of getting badly burnt. Literal numeric constants (as I recall)
default to fixed decimal. OUCH!!!
					Bennett Todd
					...{decvax,ihnp4,akgua}!mcnc!ecvax!bet

henry@utzoo.UUCP (Henry Spencer) (04/16/84)

Groan.  We have seen this one at least twice before, folks.  It *IS*
a bug; the compiler is supposed to make "i *= f" act just like
"i = i * f" except for possible side effects inside i.  Practically
all the existing compilers have this bug, but it it *STILL* a bug.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

guido@mcvax.UUCP (Guido van Rossum) (04/17/84)

bet@ecsvax.UUCP (Bennett Todd) says:

>What we have here is a type conversion problem.
>[...]  When i *= f is evaluated, the right side of the assignment
>operator is evaluated, just as before: it is the float. It is then converted
>to integer for the assignment operation: 0.2 goes to 0 in any reasonable
>conversion. BEWARE incautious mixed types: they ALWAYS ALWAYS ALWAYS bite
>back.

NO, NO, NO!  This subject has been beaten to death (in this newsgroup or
in net.unix-wizards?) a few months ago.  It is a definite compiler bug,
which unfortunately lingers around in almost all compilers available.
This makes the last quoted phrase understandable, but it's the compilers,
not the language that bites.  Compilers can be fixed.

(BTW, look in K&R: somewhere it says a *= b is treated as a = a*b
except for the side effects of computing a's address.)

--
	Guido van Rossum, "Stamp Out Basic" Committee, CWI, Amsterdam
	guido @ mcvax

crl@pur-phy.UUCP (Charles LaBrec) (04/17/84)

However, pulling out the trusty K&R says (pg 191, Sec 7.14)

	The behavior of an expression of the form E1 op= E2 may be
	inferred by taking it as equivalent to E1 = E1 op (E2) ....

So i *= .2 should be evaluated as i = i * .2, which is a very legal
mixed mode operation where i gets converted to a double, multiplied
by .2, truncated to an integer, and assigned to i.

Charles LaBrec
UUCP:		pur-ee!Physics:crl, purdue!Physics:crl
INTERNET:	crl @ pur-phy.UUCP

peters@cubsvax.UUCP (Peter S. Shenkin) (04/17/84)

Re: Bennett Todd's assertion that the problem is not a bug:

cf K&R p 41:  "In general, if... a "binary operator" has operands of different
types, the "lower" type is *promoted* to the "higher" before the
operation proceeds....

This, coupled with their assertion elsewhere that x = x op y "may be taken
as equivalent" (or words to that effect) to x op= y, would seem to indicate
that i *= f and i = i * f should evaluate the expression with i and f as
floats, then cast the result to int.  In any case, they should evaluate
the expression the same way!  If you disagree, quote me chapter and verse.

Net effect:  it's a bug!

Moral: beware implicit type conversions, since they may not do what K&R
says they do.

By the way, I'd be curious to see the results of the program on other
compilers.

{philabs,cmcl2!rocky2}!cubsvax!peters            Peter S. Shenkin 
Dept of Biol. Sci.;  Columbia Univ.;  New York, N. Y.  10027;  212-280-5517
"In accordance with the recent proclivity for clever mottos, this is mine."

jim@ism780.UUCP (04/22/84)

#R:ecsvax:-231000:ism780:12500003:000:539
ism780!jim    Apr 20 18:30:00 1984

As Dennis Ritchie pointed out the last time this came up (quite recently),
it is a bug, and it is amazing how hard people will try to convince
themselves and others that the compiler must be right, even though the
manual clearly says that "l op= r" is equivalent to "l = l op r", except
that l is only evaluated once (which means that if l has side-effects,
they only happen once; how this can be interpreted as meaning that
conversions should happen differently is beyond me).

-- Jim Balter, Interactive Systems (decvax!yale-co!ima!jim)