[comp.lang.c] Would *you* get caught by this one?

mat@mole-end.UUCP (Mark A Terribile) (01/10/89)

Here's a simple C question on a point that caught me recently.  Would *you*
get caught?

	When is     a *= b      not the same as     a = a * b   ?
-- 

(This man's opinions are his own.)
From mole-end				Mark Terribile

ark@alice.UUCP (Andrew Koenig) (01/13/89)

In article <139@mole-end.UUCP>, mat@mole-end.UUCP (Mark A Terribile) writes:
> Here's a simple C question on a point that caught me recently.  Would *you*
> get caught?
> 
> 	When is     a *= b      not the same as     a = a * b   ?

Two answers:

	1. When a has side-effects. For example:

		x[i++] *= y;
	
	is not the same as

		x[i++] = x[i++] * y;

	2. When a is fixed-point, b is floating-point, and your
	   compiler is broken.  Many compilers are broken this way.
	   For example:

		int a = 3;
		a *= 2.5;
	
	   A number of compilers will decide to truncate 2.5 to 2
	   and therefore leave a equal to 6 after this is done.
	   The right answer is, of course, 7.  Or maybe 8.  Definitely
	   not 6.

Do I pass?
-- 
				--Andrew Koenig
				  ark@europa.att.com

newsuser@LTH.Se (LTH network news server) (01/13/89)

In article <139@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
>
>	When is     a *= b      not the same as     a = a * b   ?

For example, if you have:

	#define b x + y

then:

	a *= b		<=> 	a *= (x + y)
	a = a * b	<=>	a = (a * x) + y

I strongly recommend the following book:

	Andrew Koenig: ``C Traps and Pitfalls'', Addison-Wesley Publishing
	Company, 1989. ISBN 0-201-17928-8.

Dag Bruck
-- 
Department of Automatic Control		Internet:  dag@control.lth.se
Lund Institute of Technology
P. O. Box 118				Phone:	+46 46-108779
S-221 00 Lund, SWEDEN			Fax:    +46 46-138118

swh@hpsmtc1.HP.COM (Steve Harrold) (01/14/89)

When you have a++, the results are going to be different, i.e.

	a++ *= b      is DIFFERENT from     a++ = a++ * b ;

The first case increments "a" once, the second TWICE.

tonyw@microsoft.UUCP (Tony Williams) (01/14/89)

In article <139@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
>Here's a simple C question on a point that caught me recently.  Would *you*
>get caught?
>
>	When is     a *= b      not the same as     a = a * b   ?


I think the proper answer is when your C compiler has a bug :-)
More seriously, here is one that not many C compilers get right:

	int a = 2;
	a *= 0.5;

Most compilers give you a == 0 following the *= statement, and a == 1
following a statment a = a * 0.5;
(Thanks to Jeff Smith at Warwick, UK for pointing this one out to me)

   Tony Williams

mat@mole-end.UUCP (Mark A Terribile) (01/14/89)

> Here's a simple C question on a point that caught me recently.  Would *you*
> get caught?
> 
> 	When is     a *= b      not the same as     a = a * b   ?

I've seen a number of replies, and all but one respondant has concentrated
on things like the preprocessor or C++'s potential overloading of *= .  There
was also a mention of volatile.

It's much simpler than that, and much uglier.   To give credit where credit
is due I will take the liberty of publishing part of a private correspondence:

>From: Chris Torek <mimsy.umd.edu!chris@gatech>
>
>a *= b is always equivalent if both a and b are simple variables
>or expressions (i.e., no side effects, etc.).  A number of compilers
>do miscompile int_var *= float_expr, however.
>
>Chris

Yes, they do.  Given that the issue isn't directly addressed in either K&R,
I wasn't going to come out and say which way is right, but Chris did and,
since Microsoft (at least) agrees with him, I accept his judgement on the
matter.  (I remain open to a detailed examination of dpANS).

Some compilers interpret  i *= f  as

		i *= (int) f

This is obviously not the same as

		i = (int)( i * f )

and can produce wildly improbable results if the value of f is, let us say,
0.95 .

>Subject: i *= f
>
>is supposed to mean i = (int)(i * f).  PCC simply had a bug.  (The
>old PDP-11 compiler got it right...)
>
>Chris

Since PCC did define the language for many people for many years, this
``simply'' has widespread ramifications.

Chris gets a gold star and a bottle of Bactine for the burns suffered in
discovering this.
-- 

(This man's opinions are his own.)
From mole-end				Mark Terribile

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/14/89)

In article <11480015@hpsmtc1.HP.COM> swh@hpsmtc1.HP.COM (Steve Harrold) writes:
>	a++ *= b      is DIFFERENT from     a++ = a++ * b ;
>The first case increments "a" once, the second TWICE.

Right idea, wrong example.  This one isn't legal C.

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/16/89)

In article <144@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
>Yes, they do.  Given that the issue isn't directly addressed in either K&R,

It most certainly is!  a op= b is the same as a = a op b except that
a is evaluated only once.  That has been the definition since before
K&R first edition, and of course the pANS doesn't change that.

Certainly, some compilers (including several versions of PCC)
got it wrong.  That may be reason to avoid this in your source
code, but it doesn't affect the definition of op=.

dg@lakart.UUCP (David Goodenough) (01/17/89)

From article <139@mole-end.UUCP>, by mat@mole-end.UUCP (Mark A Terribile):
> Here's a simple C question on a point that caught me recently.  Would *you*
> get caught?
> 
> 	When is     a *= b      not the same as     a = a * b   ?
> -- 
> 
> (This man's opinions are his own.)
> From mole-end				Mark Terribile

#define	a	(*(c++))

springs to mind.
-- 
	dg@lakart.UUCP - David Goodenough		+---+
							| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com		  	  +---+

gal@atux01.UUCP (G. Levine) (01/24/89)

In article <1989Jan13.085902.2057@LTH.Se>, newsuser@LTH.Se (LTH network news server) writes:
> In article <139@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
> >	When is     a *= b      not the same as     a = a * b   ?
>
> For example, if you have:
>
> 	#define b x + y
>
> then:
>
> 	a *= b		<=> 	a *= (x + y)
> 	a = a * b	<=>	a = (a * x) + y

This is why its so important to use parentheses in a #define
statement.  Changing the define statement to

	#define b (x + y)

will save a lot ot headaches!

					gary

--------------------------------------------------------------------------------
If it wasn't so cool out today, it would be warmer.
--------------------------------------------------------------------------------