[comp.lang.c] Macro help

grimlok@hubcap.clemson.edu (Mike Percy) (03/09/90)

Awhile back I saw some code which used a macro that had a do...while(0)
loop in it.  At the time I thought, hey that's a good idea, but now that I need
to do something while could use this I'm stuck.   
 
Here's my situation: 
I am reading chars. When I hit '\n' I need to skip the first 6 chars on
the next line ( anyone guess why?) and return the next char.  Effectively this
removing all "\nxxxxxx" from the stream.

I tried this:
  
#define input(ch) \ 
   ((ch) = getchar) != '\n' ? (ch) : \
   (do { int i = 5; while(i--) (void) getchar(); } while(0);), getchar()
 
But this doesn't seem to work.  Anyone that can help me out there?

jwl@ernie.Berkeley.EDU (James Wilbur Lewis) (03/09/90)

In article <8284@hubcap.clemson.edu> grimlok@hubcap.clemson.edu (Mike Percy) writes:
-Awhile back I saw some code which used a macro that had a do...while(0)
-loop in it.  At the time I thought, hey that's a good idea, but now that I need
-to do something while could use this I'm stuck.   
- 
-Here's my situation: 
-I am reading chars. When I hit '\n' I need to skip the first 6 chars on
-the next line ( anyone guess why?) and return the next char.  Effectively this
-removing all "\nxxxxxx" from the stream.
-
-I tried this:
-  
-#define input(ch) \ 
-   ((ch) = getchar) != '\n' ? (ch) : \
-   (do { int i = 5; while(i--) (void) getchar(); } while(0);), getchar()
- 
-But this doesn't seem to work.  Anyone that can help me out there?

How about this?

#define INPUT(ch) while ( ((ch) = getchar()) == '\n') \
		  { \
		     int i; \
		     for(i=1; i <= 6; i++) (void) getchar(); \
		  }

(It compiles; I haven't tested it.)   Your version has several problems:
the () is missing from the first call to getchar(), the final call to
getchar() doesn't assign anything to (ch), and worst of all, you are trying
to use a statement like do ... while within an expression, which is a
syntactic no-no.   

(Do you always want to return the _next_ character after skipping?  What
if it's another '\n'?)

I used an upper-case name to warn future maintainers that this is a macro
and not a function, so they won't be tempted to use an expression with
side effects like buf[i++] in place of ch, since the possibility of multiple
evaluation exists.  (The fact that a character is being passed instead of
a char *  _should_ tip them off if they're on the ball, but better safe
than sorry, right?)

-- Jim Lewis
   U.C. Berkeley

grimlok@hubcap.clemson.edu (Mike Percy) (03/09/90)

Thanks for the help.  People have told me some things and I have fiddled
more until I realized that, syntacticly (sp?), trying to do something like
x = (y,z)   (assign x the value of z, after also evaluating y) is not allowed
to have y be a statement, only an expression.  Thunk!  I knew better than 
that.  So I'll be trying to figure out a better alternative.     

Again:

#define INPUT() ( {do stuff until(0);} , value I really want)

x = INPUT();

simply doesn't cut it.  Life would be much easier if { statements } had a 
value.

But wait, what if I switched to ADA?? Would I be saved from this horror?
Would life be sweet and would I make 44.3% gains on my IRAs? 

Oh yeah, one preson correctly guessed why I wanted to do what I was trying to do(COBOL is not a fun language to write a standards-checker/formatter for!)