[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

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

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.
--------------------------------------------------------------------------------