[comp.os.msdos.programmer] #define thisneatmacro

a563@mindlink.UUCP (Dave Kirsch) (10/18/90)

> ctl8588@rigel.tamu.edu writes:
> 
> Msg-ID: <9286@helios.TAMU.EDU>
> Posted: 18 Oct 90 20:10:01 GMT
> 
> Org.  : TAMU
> Person: LAUGHLIN, CHET
> 
> I have a function that is called all the time by my screen handling
> routines in a program.  I'm not sure if TC is placing the two liner
> function inline even though I've set it for speed (vs. size) optimizing.
> I have been unable to write the function as a macro for all situations-
> possibly somebody knows a hack?
> 
> static void drawch(x,y,ch)
>   int x,y;
>   char ch;
> {
>   gotoxy(x,y);
>   cput(ch);
> }
> 
> I tried useing the following macro, with some success...
> 
> #define drawch(A,B,C)  {gotoxy(A,B); cput(C);}
> 
> however, the following code won't work...compiler doesn't like
> the extra ; at the end of drawch...
> 
> if (cond)
>    drawch(x,y,ch);
> else
>    printf("ICK!\n");
> 
> Any ideas out there?

Yeah, try this:

#define drawch(A, B, C) (gotoxy((A), (B)), cput((C)))

That should work in all cases, i.e. the if you showed will work. Because you
used the braces { }, the if was terminated with a ; after the last brace.  In
your previous macro, it expanded to:

if (cond)
  {gotoxy(x,y); cput(ch);};  /* NOTE extra semicolon!!! */
else
  printf("ICK!\n");

What happened is after the macro expanded, it leaves the semi-colon after the
macro in place, so the if statement was terminated, leaving a "dangling" else
statement that the compiler has no idea what to do with.

With the macro I have defined to be used instead, it expands to:

if (cond)
  (gotoxy((x), (y)), cput((ch)));
else
  printf("ICK!\n");

Which will work correctly.  I have used the comma operator to put the two
function calls together, I also encased the arguments in parenthesis so there
will be no problems in expansion when using "strange" arguments.

--
--
/// Dave 'Zoid' Kirsch UUCP: {uunet,ubc-cs}!van-bc!rsoft!mindlink!a563
Voice: (604) 585-8844       a563@mindlink.UUCP
                            Zoid@cc.sfu.ca
                      Vancouver, British Columbia
"In-no-sense?  Nonsense!" - The Art Of Noise.

ctl8588@rigel.tamu.edu (LAUGHLIN, CHET) (10/19/90)

I have a function that is called all the time by my screen handling
routines in a program.  I'm not sure if TC is placing the two liner
function inline even though I've set it for speed (vs. size) optimizing.
I have been unable to write the function as a macro for all situations-
possibly somebody knows a hack?

static void drawch(x,y,ch)
  int x,y;
  char ch;
{
  gotoxy(x,y);
  cput(ch);
}

I tried useing the following macro, with some success...

#define drawch(A,B,C)  {gotoxy(A,B); cput(C);}

however, the following code won't work...compiler doesn't like
the extra ; at the end of drawch...

if (cond)
   drawch(x,y,ch);
else
   printf("ICK!\n");

Any ideas out there?
+---------------------------------------------------------------+
| Chet Laughlin                  CTL8588@RIGEL.TAMU.EDU         |
|   "I have no opinions as I          (128.194.4.4)             |
|    do not exist, my lawyers                                   |
|    told me so."                                               |
+---------------------------------------------------------------+

manning@nntp-server.caltech.edu (Evan Marshall Manning) (10/19/90)

ctl8588@rigel.tamu.edu (LAUGHLIN, CHET) writes:


#define drawch(A,B,C)  do {gotoxy(A,B); cput(C);} while (0)

is a standard hack.  Another is:

#define drawch(A,B,C)  gotoxy(A,B), cput(C)

(You'll probably get a million similar answers, but better than none....)

***************************************************************************
Your eyes are weary from staring at the CRT for so | Evan M. Manning
long.  You feel sleepy.  Notice how restful it is  |      is
to watch the cursor blink.  Close your eyes.  The  |manning@gap.cco.caltech.edu
opinions stated above are yours.  You cannot       | manning@mars.jpl.nasa.gov
imagine why you ever felt otherwise.               | gleeper@tybalt.caltech.edu

allebrandi@inland.com (Tom Allebrandi) (10/19/90)

In article <9286@helios.TAMU.EDU>, ctl8588@rigel.tamu.edu (LAUGHLIN, CHET) writes:
> I tried useing the following macro, with some success...
> 
> #define drawch(A,B,C)  {gotoxy(A,B); cput(C);}
> 
> however, the following code won't work...compiler doesn't like
> the extra ; at the end of drawch...
> 
> if (cond)
>    drawch(x,y,ch);
> else
>    printf("ICK!\n");
> 

Think about what you are telling the compiler. What you have typed above
is exactly equivalent to

	if (cond)
	   {gotoxy(A,B); cput(C);};	(1)
	else
	   printf("ICK!\n");

The way I read the language definition in K&R, line (1) is not legal
syntax. However, this is legal:

	   {{gotoxy(A,B); cput(C);};}

meaning that you should do this:

	if (cond)
	  {drawch(x,y,ch);}
	 ... 

Another approach would be to define your macro as

	#define drawch(A,B,C)  gotoxy(A,B), cput(C)

--- Tom
Tom Allebrandi             | Vice-char and mail guru, VMSnet WG, DECUS VAX SIG
Inland Steel Research Labs | Internet:  allebrandi@inland.com
East Chicago, IN           | UUCP:      ...!uunet!inland!allebrandi
219 399 6306               | DECUServe: allebrandi     BIX: ta2

otto@tukki.jyu.fi (Otto J. Makela) (10/19/90)

In article <9286@helios.TAMU.EDU> ctl8588@rigel.tamu.edu (LAUGHLIN, CHET)
writes:
	[how to convert function to macro ?]
   I tried useing the following macro, with some success...
   #define drawch(A,B,C)  {gotoxy(A,B); cput(C);}
   however, the following code won't work...compiler doesn't like
   the extra ; at the end of drawch...
   if (cond)
      drawch(x,y,ch);
   else
      printf("ICK!\n");

The classic solution (which perhaps should go into the FAQ posting) is to do:
#define	drawch(A,B,C)	do { gotoxy(A,B); cput(C); } while(0)
which makes the macro work correctly inside if's.  A good optimizing compiler
will remove the extra caused by 'do {} while(0)'

Of course, one thing you could also do is
#define	drawch(A,B,C)	( gotoxy(A,B), cput(C) )
(remember, a comma is the discard-value-of-1st-argument-return-value-of-2nd
operator if outside function evocations).  This is a bit more risky, however,
since things could get hairy if gotoxy or cput are also macros.

This will undoubtedly be the main topic in this newsgroup for the next three
weeks, as everyone will post their favorite answer as in the count-the-bits
and the hash function problems.
--
   /* * * Otto J. Makela <otto@jyu.fi> * * * * * * * * * * * * * * * * * * */
  /* Phone: +358 41 613 847, BBS: +358 41 211 562 (CCITT, Bell 24/12/300) */
 /* Mail: Kauppakatu 1 B 18, SF-40100 Jyvaskyla, Finland, EUROPE         */
/* * * Computers Rule 01001111 01001011 * * * * * * * * * * * * * * * * */

fisher@sc2a.unige.ch (Markus Fischer) (10/19/90)

In article <9286@helios.TAMU.EDU>, ctl8588@rigel.tamu.edu (LAUGHLIN, CHET)
writes:
>
> [...]
>
> I tried useing the following macro, with some success...
> 
> #define drawch(A,B,C)  {gotoxy(A,B); cput(C);}
> 
> however, the following code won't work...compiler doesn't like
> the extra ; at the end of drawch...
> 
> if (cond)
>    drawch(x,y,ch);
> else
>    printf("ICK!\n");
> 
> Any ideas out there?

If you really want it, try one of the following:

#define drawch(A,B,C)   do { gotoxy((A),(B)); cput(C); } while(0)
#define drawch(A,B,C)   gotoxy((A),(B)), cput(C)
#define drawch(A,B,C)   cputc(( gotoxy((A),(B)), (C) ))

whichever you like.

All four (your's included) follow the general rule for lowercase macros,
which is to use every parameter exaclty once.  Thus

	drawch( col++, row, *(string++) );

works as expected.

The last one is neat, it reads: call function cputc with parameter
"( evaluate gotoxy, with params A and B, drop the return value, use C )",
and keep return value of cputc for future use.  ( In fact the equivalent
`putch' of TC returns nothing... )

Enjoy

Markus Fischer, Dpt. of Anthopology, Geneva.

ctl8588@rigel.tamu.edu (LAUGHLIN, CHET) (10/20/90)

In article <9286@helios.TAMU.EDU>, ctl8588@rigel.tamu.edu (LAUGHLIN, CHET) writes...
>I have a function that is called all the time by my screen handling


Thanks to all those that replied.  Yes, the following code works in all
situations (that occur in my code...d:)

#define drawchar(A,B,C) (gotoxy(A,B), cput(C))

now a question.  why does the function call to gotoxy work if its
not ended with a semi-colon?

Thanks again,
+---------------------------------------------------------------+
| Chet Laughlin                  CTL8588@RIGEL.TAMU.EDU         |
|   "I have no opinions as I          (128.194.4.4)             |
|    do not exist, my lawyers                                   |
|    told me so."                                               |
+---------------------------------------------------------------+