pkl@daisy.UUCP (Peter K. Lee) (01/26/85)
> Whenever I define a macro to be an expression, I put parens around it > to avoid surprises. Similarly, whenever I define a macro to be a > (compound) statement, I put braces around it. There are two places > where braces cause problems: IF statements with ELSE clauses and > DO statements: > hugh@hcrvx1 I learned this from Dave Ungar while working on the Berkeley Smalltalk project. # define macro(args)\ if (1) {\ /* macro body */\ /* goes here */;\ }\ else Notice that the trailing "else" will take care of the ";". A macro defined this way can go wherever a legal C statement can go because this IS a legal C statement (when you call it as macro(args);). If you think that "if (1)" is silly and may generate inefficient code, you better go find a better compiler. -- -- Peter Lee ...{ucbvax!amd,decwrl,ihnp4}!nsc!daisy!pkl [No news is good news]
hugh@hcrvx1.UUCP (Hugh Redelmeier) (01/28/85)
In article <33@daisy.UUCP> pkl@daisy.UUCP (Peter K. Lee) writes: >> whenever I define a macro to be a >> (compound) statement, I put braces around it. There are two places >> where braces cause problems: IF statements with ELSE clauses and >> DO statements: >> hugh@hcrvx1 > # define macro(args)\ > if (1) {\ > /* macro body */\ > }\ > else >If you think that "if (1)" is silly and may generate inefficient >code, you better go find a better compiler. I think this is silly. I guess I better go find a better compiler, but for what language? Seriously, several people have suggested this, but I remain repelled. I think I will stick with my braces and accept the occasional syntax error (they are easy to fix, and braces never lead to undetected errors).
ksbszabo@wateng.UUCP (Kevin Szabo) (01/29/85)
In article <33@daisy.UUCP> pkl@daisy.UUCP (Peter K. Lee) writes: > # define macro(args)\ > if (1) {\ > /* macro body */\ > }\ > else I am also not going to use Peter's suggestion because it too can cause un-obvious behavior, but this time if the user makes a small syntax error. Suppose I forget the semicolon when I call the macro? macro( args ) next_statment; Voila! next_statement is NEVER called because it is gobbled up in the `else' clause of the expanded macro. Yuck...that would take hours to find. I also find the macro definition hard to read...whenever I see an `else' I expect it to be controlling something. Very confusing. Kevin -- Kevin Szabo watmath!wateng!ksbszabo (U of Waterloo VLSI Group, Waterloo Ont.)
arnold@gatech.UUCP (Arnold Robbins) (02/01/85)
Okay, folks, we've discussed this one before. The macro #define assert(x) if (!(x)) die_miserably("x bombed\n") doesn't work because of problems with a missing else. It was suggested #define assert(x) if (!(x)) die_miserably("x bombed\n") else /* no ; */ but if the real semicolon is left off by accident, the next statement is eaten. Now, putting braces around it also won't work: #define assert(x) { if (!(x)) die_miserably("x bombed\n"); } because of this: if (something) assert (something_else);/* <--- this ; will bomb cc */ else another_thing_altogether(); So, as has been mentioned before, the two ways to do this are #define assert(x) do { if (!(x)) die_miserably("x bombed\n"); } while (0) which will get executed exactly once, and protects the macro syntactically. This also should not pose a code generation/efficiency problem. The other way is this: #define assert(x) if(x) ; else die_miserably ("x bombed\n") which will also work. This topic has gone around (several times) before. I am hoping that this note will settle it, so that we can discuss something else. Thanks, -- Arnold Robbins CSNET: arnold@gatech ARPA: arnold%gatech.csnet@csnet-relay.arpa UUCP: { akgua, allegra, hplabs, ihnp4, seismo, ut-sally }!gatech!arnold Help advance the state of Computer Science: Nuke a PR1ME today!
alex@ucla-cs.UUCP (02/03/85)
[Debugged] Wherever possible a macro should expand into an expression. #define assert(x) (!(x) ? die_miserably("x bombed\n") : 1) will do what is desired--if x is untrue, die_miserably will be executed. (Maybe this could even be improved by casting the result to void?)
aug@cybvax0.UUCP (Alan Green) (02/04/85)
> Okay, folks, we've discussed this one before. The macro > > #define assert(x) if (!(x)) die_miserably("x bombed\n") > > doesn't work because of problems with a missing else. It was suggested > ... Whats wrong with: #define assert(cond) ( (cond) ? 0 : \ (fprintf (stderr, \ "assertion failed at line %d in file %s\n", \ __LINE__, __FILE__), \ exit(-1) \ ) \ ) ??? harvard!cybvax0!aug
jss@sjuvax.UUCP (J. Shapiro) (02/05/85)
[Aren't you hungry...] In article <33@daisy.UUCP> pkl@daisy.UUCP (Peter K. Lee) writes: > # define macro(args)\ > if (1) {\ > /* macro body */\ > }\ > else Kevin Szabo points out that: > macro( args ) > next_statment; fails in this macro, and is hard to find. If, hoever, one writes else; instead of else the problem goes away. Personally I still like my macros simple. I favor the notion of intelligent compilation and elimination of redundant/unused object modules as more valuable then #define'd pseudofunctions. If only there were a way to say "now about this function - it goes inline" in C. It's been done in Franz Lisp - take a look at defmacro.... Any volunteers? :-)
ndiamond@watdaisy.UUCP (Norman Diamond) (02/08/85)
> > > # define macro(args)\ > > > if (1) {\ > > > /* macro body */\ > > > }\ > > > else > > > -- P. Lee > > > > macro( args ) > > next_statment; > > fails in this macro, and is hard to find. > > -- K. Szabo > > If, hoever, one writes > else; > instead of > else > the problem goes away. > -- J. Shapiro Then: if (condition) macro( args ); else other_stuff; gives a syntax error! (OK it's easier to find, but then suppose the macro changes to a function. OK, it's still easier to find. BUT IT'S STILL OBNOXIOUS!) -- Norman Diamond UUCP: {decvax|utzoo|ihnp4|allegra|clyde}!watmath!watdaisy!ndiamond CSNET: ndiamond%watdaisy@waterloo.csnet ARPA: ndiamond%watdaisy%waterloo.csnet@csnet-relay.arpa "Opinions are those of the keyboard, and do not reflect on me or higher-ups."
bsa@ncoast.UUCP (Brandon Allbery) (02/11/85)
> Article <1924@wateng.UUCP>, from ksbszabo@wateng.UUCP (Kevin Szabo) +---------------- | In article <33@daisy.UUCP> pkl@daisy.UUCP (Peter K. Lee) writes: | > # define macro(args)\ | > if (1) {\ | > /* macro body */\ | > }\ | > else | | I am also not going to use Peter's suggestion because it too can cause | un-obvious behavior, but this time if the user makes a small syntax | error. Suppose I forget the semicolon when I call the macro? | ... | I also find the macro definition hard to read...whenever I see an | `else' I expect it to be controlling something. Very confusing. The answer was posted about 3 months ago. #define macro(args)\ do\ {\ /* macro body */\ }\ while (0) The body is executed exactly once, since the condition isn't found to b false until the end... and a missing semicolon will show up as a syntax error, which is reasonable. Brandon (bsa@ncoast.UUCP) -- Brandon Allbery, decvax!cwruecmp!ncoast!bsa, "ncoast!bsa"@case.csnet (etc.) 6504 Chestnut Road, Independence, Ohio 44131 +1 216 524 1416 (or what have you)