[comp.lang.c] Turbo Trouble

d88-jwa@nada.kth.se (Jon W{tte) (06/03/89)

I recently ran into a problem (bug ?) in Turbo C 2.0 using #define:

#define SetRect(rectp, t, l, b, r)\
(rectp)->top = t, (rectp)->left = l, (rectp)->bottom = b, (rectp)->right = r

This macro later gets called by:
[definitions, among them struct rect { int left, top .......]

        rect r;

        SetRect(&r, 20, 20, 200, 400);

This should be fairly legal. I tried to compile it, and my machine
(Victor V286A with 640 kBytes RAM) hung on me:
Internal Stack Overflow -- System halted

Can anyone there post or email an answer ? Is this a known bug ?
There should not have been any memory problems, since all of the
code was a bit under 100 lines... Plus a few standard libs (Graph.h,
stdio.h and stdlib.h) The memory left meter didn't go below 100k,
I'm fairly sure. Oh, by the way, Turbo C places compilation
warnings and errors wrong in the source if you have macros longer
than one line.

For those who want to know: Yes, I am writing a "Compatibility"
package for Macintosh -> PC ports, personal use.

-- 
 __       Jon W{tte (The dread Smiley Shark) email:h+@nada.kth.se
/  \      (+46 (0) 8 258 268)
   /---   (c) 1989 Yessbox Allright Professional Products Inc. - Y.A.P.P.I.
  /       -- No More --

cline@sun.soe.clarkson.edu (Marshall Cline) (06/08/89)

In article <1159@draken.nada.kth.se> d88-jwa@nada.kth.se (Jon W{tte) writes:

>Summary: Turbo C 2.0 hangs on me !
>I recently ran into a problem (bug ?) in Turbo C 2.0 using #define:
>#define SetRect(rectp, t, l, b, r)\
>(rectp)->top = t, (rectp)->left = l, (rectp)->bottom = b, (rectp)->right = r

NOTE FOR ALL MACRO-USERS:  You really must be careful about how you use the
formal parameters inside macros.  In particular, each "t", "l", "b" and "r"
in the above "#define" should be parenthesized.  Ie: Change it to:
#define SetRect(rectp, t, l, b, r)\
 (rectp)->top=(t), (rectp)->left=(l), (rectp)->bottom=(b), (rectp)->right=(r)
              ^^^                ^^^                  ^^^                 ^^^
PERSONAL_OPINION_BEGINS {
	flame_thrower = OFF;
	As a statement of style, I tend to over-parenthesize assignments and
	comma-exprs.  Ex: My tendancy is to say: "(foo=bar),(baz=barf)" to
	emphasize the order.  The other (personal preference) way is with
	a "do {...} while (0)" statement, as in:
#	define SetRect(rectp, t, l, b, r)	\
		do {	(rectp)->top = (t);	\
			(rectp)->left = (l);	\
			(rectp)->bottom = (b);	\
			(rectp)->right = (r);	\
		} while (0)
} /* PERSONAL OPINION ENDS */

>This macro later gets called by:
>[definitions, among them struct rect { int left, top .......]
>        rect r;
>        SetRect(&r, 20, 20, 200, 400);
>This should be fairly legal. I tried to compile it, and my machine
>(Victor V286A with 640 kBytes RAM) hung on me:
>Internal Stack Overflow -- System halted

I had a problem with some Turbo-C code similar to this.  Borland has
the cpp pass "built-in" to the compiler itself (for speed purposes, I'm
sure).  Anyway, "cpp" expands your macro out to a long line of macro-less
code.  This long line is then re-parsed as C code.  The problem I had
disappeared when I made the macros shorter.

I suspect the Turbo-C compiler uses something like "gets()" rather than
"fgets()" to snatch up the long lines.  Either than or it simply overruns
a buffer somewhere.  In any event, when I replaced macros with either
shorter macros or function calls, the problem vanished.  (I had macros
inside macros inside macros -- a mess).

The point is that the _SAME_EXACT_ code ran PERFECTLY on our Un*x boxes,
but failed miserably under Turbo-C.  The errors generated were really
wierd too.  Like a divide by zero runtime error occuring in a "x = 1;"
Twilight zone stuff.

Cheers.
Marshall
--
	________________________________________________________________
	Marshall P. Cline	ARPA:	cline@sun.soe.clarkson.edu
	ECE Department		UseNet:	uunet!sun.soe.clarkson.edu!cline
	Clarkson University	BitNet:	BH0W@CLUTX
	Potsdam, NY  13676	AT&T:	(315) 268-6591