Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site wateng.UUCP Path: utzoo!watmath!wateng!ksbszabo From: ksbszabo@wateng.UUCP (Kevin Szabo) Newsgroups: net.sources.bugs Subject: Re: C-Debug package, possible problems depending on program structure Message-ID: <1885@wateng.UUCP> Date: Mon, 21-Jan-85 04:08:04 EST Article-I.D.: wateng.1885 Posted: Mon Jan 21 04:08:04 1985 Date-Received: Mon, 21-Jan-85 04:46:34 EST Distribution: net Organization: VLSI Group, U of Waterloo Lines: 69 This bug affects users of Fred Fish's C Debugging Package. You may note that all of Fred's macros of the DBUG_X variety (x=1,2,3,4..) 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; Admittedly this program structure should really never occur, but it could surprise someone someday. 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 );};} I like many of the idea's in Fred's package and I will probably incorporate them into my own runtime macro's. One thing I would like to know is: Does anybody have a nice way of handling variable length argument lists to CPP? Since my variable names are usually meaningful I would like a macro that uses the variable names to create the format string. Thus I could do the following... int blood, sweat; float tears; ...... DBUG( LEVEL, "churchill", "%d,%d,%f", blood, sweat, tears ); Ideally the macro would change all this to if( debug & LEVEL ) { if( keyword("churchill) ) printf(" blood =%d, sweat= %d, tears= %f",....); (I use the bit vector LEVEL to select various areas of the package to be elegible for debugging). The only thing I have been able to come up with is the following HACK(!) DBUG( LEVEL, "keyword", "fmt", ( variable, argument, list )); #define DBUG( level, key, fmt, args ) {\ extern DebugLevel;\ if( DebugLevel & level ) {\ DebugStoreStrings( key, fmt,_LINE_, _FILE_,"args" );\ DebugPassValues args;\ }\ } Of course DebugPassValues() has to look at the format strings and use VARARGS stuff to decode its argument list. Does the extra set of parantheses used to fool CPP into thinking that there is only one set of arguments really gross anybody out? Is it portable at all? Especially the call to DebugPassValues, which requires CPP to retain the parantheses and thus create a valid function call? Kevin -- Kevin Szabo watmath!wateng!ksbszabo (U of Waterloo VLSI Group, Waterloo Ont.)