Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!van-bc!ubc-cs!fornax!john From: john@fornax.UUCP (John Simmons) Newsgroups: comp.lang.c Subject: TRANSPARENTLY adding arguments to a functions arg list Keywords: macros, variable-length arg lists Message-ID: <1092@fornax.UUCP> Date: 17 Aug 90 17:12:15 GMT Distribution: na Organization: School of Computing Science, SFU, Burnaby, B.C. Canada Lines: 105 I have a set of functions in a standard library. The library is used in writing proceduralized code for VLSI design. The functions can be divided into two main groups: those that take a fixed number of arguments and those that take an indeterminate number of arguments. An example of the former is the function layer( arg1 ); which sets the current physical layer. An example of the latter is the function polygon( x1,y1, x2,y2, x3,y3, ... , xN,yN, END ); which creates a polygon with vertices (x1,y1), (x2,y2), (x3,y3), ... , (xN,yN). The argument 'END' is a sentinel defined as follows: #define END ( 1 << ( 8*(sizeof(int) - 1 )) ) ------------------------------------------------------------------------------- I would like to modify all such functions so that they expect two more arguments, namely the preprocessor macros __FILE__ and __LINE__ . This would allow me to report to the user the location of any error that the function's error-checking routines find. It also has great potential as a method of linking an object to the line of source code that created it. Re-writing the functions is "easy". The "trick" is that: 1.) The user must NOT have to enter these new arguments when invoking the function. (It's "too much work" for them.) (They will probably forget at least some of the time.) (In general, it's something that should be transparent to them.) 2.) While the functions themselves can be re-written, the existing source code that USES them cannot. (It can be re-compiled, but the source itself cannot be changed.) (It would be "too much work".) (It would be "too hard" to contact all users.) (The BOSS SAYS SO!) 3.) The macros MUST be the FIRST two arguments in the argument list. (It is often impractical to step through long argument lists more than once and the values of these macros are needed BEFORE the processing of the argument is finished.) For the functions that take a fixed number of arguments, the method is easy, just use a defined macro like this: #define layer( arg1 ) layer_new( __FILE__, __LINE__, arg1 ) For the functions that take an indeterminate number of arguments, I cannot come up with a straight forward method because C apparently has no mechanism for defining MACROS which take a variable number of arguments. I have come up with two methods of getting around this. The first is to do this: ------------------------------------------------------------------------------- #define polygon new_function( __FILE__, __LINE__ ); polygon_new This has a severe problem because the macro "polygon" expands into TWO statements which causes behavior that the user cannot anticipate in situations like the following: if( condition ) polygon( x1,y1, x2,y2, x2,y3, END ); which expands to if( condition ) new_function( __FILE__, __LINE__ ); polygon_new( x1,y1, x2,y2, x2,y3, END ); and hence always executes the call to the 'polygon_new()' function. It also makes it impossible for the 'polygon()' function to return a function to the calling program. ------------------------------------------------------------------------------- The second is to use the comma-operator and do this: ------------------------------------------------------------------------------- #define polygon ( ( new_function(__FILE__,__LINE__), polygon_new which requires that the sentinel also be redefined as: #define END ( 1 << ( 8*(sizeof(int) - 1 )) ) )) ^^ || Two NEW brackets. While this eliminates both of the problems mentioned above it creates one minor new one, namely that the values of __FILE__ and __LINE__ are not directly available to the 'polygon()' function. I can get around this problem by having the function 'new_function()' assign those values to global variables, but by then the solution is starting to look inelegant. ------------------------------------------------------------------------------- Can anyone think of a way to include the two arguments at the beginning of the variable-length argument list that satisfies all the criteria listed above? Thank you, John L. Simmons, Department of Computing Science, Simon Fraser University john@cs.sfu.ca