C-Debug package, possible problems depending on program structure

Hugh Redelmeier hugh at hcrvx1.UUCP
Tue Jan 22 07:11:30 AEST 1985


In article <1885 at wateng.UUCP> ksbszabo at wateng.UUCP (Kevin Szabo) writes:
>You may note that all of Fred's macros ...
>have the form:
>
>#define	DBUG_2( keyword, format ) \
>	if(_db_on) {_dp_printf_( __LINE__, keyword, format );}
>
>In the very rare case of the following usage, the `else' clause will
>incorrectly bind to the `if(_db_on)' provided in the macro.
>
>	if( some_thing_worth_noting_happens )
>		DBUG_2( "interesting", "info" );
>	else
>		do the normal thing;
>
>... The fix is to enclose the macro's in another
>set of {}.
>
>#define	DBUG_2( keyword, format ) \
>	{if(_db_on) {_dp_printf_( __LINE__, keyword, format );};}
>
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:

void proc() { ... }
#define mac()	{ ... }

	if (...) mac(); else ...;  <---- wrong!
	if (...) mac()  else ...;  <---- right
	if (...) proc(); else ...; <---- right
	if (...) proc()  else ...; <---- wrong!

	if (...) { proc_or_mac(); } while (...); <---- best?

The same examples apply to DO.  In fact, it applies even
if the macro definition ends in semicolon, without the braces:
#define mac()	...;

I think this shows how the following three features of C
don't combine perfectly:
- semicolons as terminators (as opposed to separators)
- semicolons DON'T terminate blocks
- statement composition is not done with bracketing
  constructs (except for {})

PS: How often have you forgotten to put the semicolon after
    an initializer contained in braces?
int primes[] = {2, 3, 5, 7, };

PPS: But thank goodness we can use the commas in an initializer
     as terminators (e.g. last comma above).



More information about the Comp.lang.c mailing list