gordon@mimir.cs.cornell.edu (Jeffrey Adam Gordon) (05/03/90)
I want to have a DEBUG flag which controls whether diagnostic printfs are executed or not. The obvious way to do this is: #ifdef DEBUG printf ("debugging information"); #endif DEBUG But its a pain to have to type the #ifdef ... #endif all the time, and its less readable than simply having: DEBUG ("debugging information"); Now, I can use the latter format if I #define DEBUG printf but then how do I turn DEBUG off? I have though of doing the following (which is not very elegant but I thought it would work): #ifdef DODEBUG # define DEBUG printf # define ENDDEBUG ; #else # define DEBUG /* # define ENDDEBUG */ #endif DODEBUG which would allow the following syntax for debugging DEBUG ("the value is %d", val); ENDDEBUG Unfortunately, I can't figure out how to #define something to be equal to "/*" sinece "/*" always seems to be interpreted as the start of a comment. Well, I've been rambling trying to describe the problem. Basically, does anyone have an idea how I can do the above easily and elegantly? Thanks for reading. - Jeff
thornley@cs.umn.edu (David H. Thornley) (05/04/90)
In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey Adam Gordon) writes: >I want to have a DEBUG flag which controls whether diagnostic printfs >are executed or not. > >The obvious way to do this is: > >#ifdef DEBUG > printf ("debugging information"); >#endif DEBUG How about #ifdef DEBUG #define D(X) X #else #define D(X) #endif and D(printf("debugging information\n");) If DEBUG is defined, anything in D() is used as is; if not, anything in D() is disregarded. It seems to work for me. David Thornley
CMH117@psuvm.psu.edu (Charles Hannum) (05/04/90)
#ifdef DEBUG #define debug(x) printf x #else #define debug(x) #endif Then, you can just use something like: debug(("%s\n","This is a test.")); (<=== This is an EXAMPLE; it's not meant to be efficient, just to emphasize the syntax!!!!) in your code. Just like printf(), except you need *two* parentheses around the argument list. I've been using this trick for years. Virtually, - Charles Martin Hannum II PennMUD Design Team - (Resident) Programmer (That's Charles to you!) "Those who say a thing cannot be done should Please send mail to: under no circumstances stand in the way of hannum@haydn.psu.edu he who is doing it." - a misquote
karl@MorningStar.Com (Karl Fox) (05/04/90)
In article <40628@cornell.UUCP> gordon@mimir.cs.cornell.edu (Jeffrey Adam Gordon) writes:
I want to have a DEBUG flag which controls whether diagnostic printfs
are executed or not.
The obvious way to do this is:
#ifdef DEBUG
printf ("debugging information");
#endif DEBUG
But its a pain to have to type the #ifdef ... #endif all the time, and
its less readable than simply having:
DEBUG ("debugging information");
Now, I can use the latter format if I
#define DEBUG printf
but then how do I turn DEBUG off?
Here is a not-too-gross method I have seen suggested (and used):
# define DEBUG(a) printf a
or, to disable it,
# define DEBUG(a)
Then, call it with a double set of outer parentheses:
DEBUG(("Warning: user %s has an ugly face!\n", user_name));
It even works as the THEN clause of an IF statement.
--
Karl Fox, Morning Star Technologies karl@MorningStar.COM
wallace@oldtmr.enet.dec.com (Ray Wallace) (05/04/90)
In article <4247@tekfdi.FDI.TEK.COM>, wallyk@tekfdi.FDI.TEK.COM (Wally Kramer) writes... >In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey Adam Gordon) >writes: >>I want to have a DEBUG flag which controls whether diagnostic printfs >>are executed or not. > DEBUG (("informative message #1: j = %d, k = %d", j, k)); > /* note extra parens surrounding normal printf parameters */ Why not just do this - #define BITCH /* IE: don't print it */ #define DEBUG printf /* IE: do print it */ main( ) { BITCH( "What the <%s> is going on?\n", "hell" ); DEBUG( "%d - nothing.\n%d - something.\n", 1, 2 ); } When the "debug" macro is defined as nothing then the stuff in paranthesis gets eveluated as an expresion(s) but thats all. When the "debug" macro is defined as printf then your standard function call to printf occurs. There is no need for an extra set of parenthesis. --- Ray Wallace (INTERNET,UUCP) wallace@oldtmr.enet.dec.com (UUCP) ...!decwrl!oldtmr.enet!wallace (INTERNET) wallace%oldtmr.enet@decwrl.dec.com ---
escher@Apple.COM (Michael Crawford) (05/04/90)
In article <1990May3.192347.12973@cs.umn.edu> thornley@cs.umn.edu (David H. Thornley) writes: >In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey Adam Gordon) writes: >>I want to have a DEBUG flag which controls whether diagnostic printfs >>are executed or not. >> >>The obvious way to do this is: >> >>#ifdef DEBUG >> printf ("debugging information"); >>#endif DEBUG > >How about >#ifdef DEBUG >#define D(X) X >#else >#define D(X) >#endif > >and >D(printf("debugging information\n");) more elegant still: #ifdef DEBUG #define fDebug( x ) fprintf x #define Debug( x ) printf x #else #define fDebug( x ) #define Debug( x ) #endif fDebug(( stderr, "debugging info" )); Debug(( "debugging info" )); be sure to do the defining of DEBUG on the CC command line, with a nifty setup in your makefile: D= CFLAGS = ${D} foo: foo.o cc -o foo foo.o foo.o: foo.c cc -c ${CFLAGS} foo.c Then your command line might be: alias md 'make D=-DDEBUG' touch foo.c md and you will turn on debugging in foo.c. Read Robert Ward's book "Debugging C". It is a gold mine. Mostly oriented toward DOS, but much of what is in it is applicable anywhere. Also, get a source level debugger. You may have sdb or dbx on Unix systems, SADE or ThinkC on Macintosh, or Codeview, and I think Turbo C, on the PC. The Free Software Foundation's GDB is available for Unix for free and is much better than dbx or sdb, IMHO. When you learn to use them effectively, it is a lot better than embedding code in your source -- less recompiling. -- Michael D. Crawford Oddball Enterprises Consulting for Apple Computer Inc. 606 Modesto Avenue escher@apple.com Santa Cruz, CA 95060 Applelink: escher@apple.com@INTERNET# oddball!mike@ucscc.ucsc.edu The opinions expressed here are solely my own. Free Lithuania.
ronnie@mindcrf.UUCP (Ronnie Kon) (05/04/90)
In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey Adam Gordon) writes: >I want to have a DEBUG flag which controls whether diagnostic printfs >are executed or not. > [ lots of stuff deleted ] How about: #if WANT_DEBUGGING # define DEBUG(a,b,c,d,e) printf(a,b,c,d,e) #else # define DEBUG(a,b,c,d,e) #endif This is ugly, in that you must always supply a fixed number of parameters, but it's quick and easy. You can also use multiple definitions, DEBUG1, DEBUG2, etc, each taking a different number of parameters. If your application is not real-time, you can also make DEBUG a real routine, which does nothing if your definition is not turned on, and a printf if it is. This causes an overhead of a few microseconds on an average machine (say a 10MHz 68000) each call. Hope this helps. Ronnie -- ------------------------------------------------------------------------------- Ronnie B. Kon | "The answers to life's problems aren't at kon@mindcraft.com | the bottom of a bottle: they're on TV!" ...!{decwrl,ames}!mindcrf!ronnie | -- Homer Simpson -------------------------------------------------------------------------------
davidsen@sixhub.UUCP (Wm E. Davidsen Jr) (05/04/90)
In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey Adam Gordon) writes: | I want to have a DEBUG flag which controls whether diagnostic printfs | are executed or not. #ifdef DEBUG #undef DEBUG /* prevent warning from redef */ #define DEBUG(x) printf x #else #define DEBUG(x) #endif To use: DEBUG(("Any # of args: %d\n", whatever)); The secret is in having the 2nd level of parens in the invocation of DEBUG and no parens in the expansion. Works like a charm! -- bill davidsen - davidsen@sixhub.uucp (uunet!crdgw1!sixhub!davidsen) sysop *IX BBS and Public Access UNIX moderator of comp.binaries.ibm.pc and 80386 mailing list "Stupidity, like virtue, is its own reward" -me
dig@peritek.UUCP (Dave Gotwisner) (05/04/90)
In article <40628@cornell.UUCP>, gordon@mimir.cs.cornell.edu (Jeffrey Adam Gordon) writes: > I want to have a DEBUG flag which controls whether diagnostic printfs > are executed or not. > > The obvious way to do this is: > > #ifdef DEBUG > printf ("debugging information"); > #endif DEBUG > > But its a pain to have to type the #ifdef ... #endif all the time, and > its less readable than simply having: > > DEBUG ("debugging information"); Agreed. > > Now, I can use the latter format if I > > #define DEBUG printf > > but then how do I turn DEBUG off? Having read some of the other responses, I have yet to see the one I use: #ifdef DEBUG # define Dprintf printf #else # define Dprintf if #endif This only needs to be included in a common header file, then, if you do: Dprintf("Input value is %d\n", 10); you get the following if DEBUG is defined: printf("Input value is %d\n", 10); and the following if DEBUG is not defined: if ("Input value is %d\n", 10); The semicolon will terminate the if, so, unless the debug printf has an else immediatly after it, this will work. There is some run time overhead (unless your compiler optimizes "if (statement);" away because it never does anything), but the overhead should be small. -- ------------------------------------------------------------------------------ Dave Gotwisner UUCP: ...!unisoft!peritek!dig Peritek Corporation ...!vsi1!peritek!dig 5550 Redwood Road Oakland, CA 94619 Phone: 1-415-531-6500
dsmythe@netcom.UUCP (Dave Smythe) (05/04/90)
It seems to me that if you want to go the instrumentation route, as opposed to the debugger route, then you might want to look at the dbugsys package (I think that there were at least 2 kinds) posted a while back to c.s.misc or c.s.unix. If I recall correctly, it does all of that kind of DEBUG stuff as well as giving you run-time control of the level of debugging info that you want to see (foo -x4 , or something like that). There were quite a variety of functions there for many other purposes as well. D
silvert@cs.dal.ca (Bill Silvert) (05/04/90)
In the recent postings there were a number of solutions to the problem of defining a function DEBUG which optionally works like printf. Only one addresses the fact that debugging information should preferably go to stderr: In article <8060@goofy.Apple.COM> escher@Apple.COM (Michael Crawford) writes: >more elegant still: > >#ifdef DEBUG >#define fDebug( x ) fprintf x >#define Debug( x ) printf x >#else >#define fDebug( x ) >#define Debug( x ) >#endif > >fDebug(( stderr, "debugging info" )); >Debug(( "debugging info" )); Is there a way to define Debug so that Debug(x, y, z,...) can optionally either do nothing or generate fprintf(stderr, x, y, z,...) with an arbitrary number of arguments? Crawford's method still requires specific mention of stderr in each debug line. -- William Silvert, Habitat Ecology Division, Bedford Inst. of Oceanography P. O. Box 1006, Dartmouth, Nova Scotia, CANADA B2Y 4A2. Tel. (902)426-1577 UUCP=..!{uunet|watmath}!dalcs!biomel!bill BITNET=bill%biomel%dalcs@dalac InterNet=bill%biomel@cs.dal.ca
passaret@brahe.crd.ge.com ("Mr. Mike" Passaretti) (05/04/90)
In article <40628@cornell.UUCP> gordon@mimir.cs.cornell.edu (Jeffrey Adam Gordon) writes: # # I want to have a DEBUG flag which controls whether diagnostic printfs # are executed or not. # # [....] # # - Jeff Fred Fish has produced an excellent set of macros for C which do just this and a lot more. The basic form of use is as follows (forgive me if this is a bit long). #include "dbug.h" main(argc, argv) int argc; char *argv[]; { int foo; DBUG_ENTER("main"); DBUG_PROCESS(argv[0]); for (i=1;i<argc && argv[i][0]=='-';i++) { switch(argv[i][1]) { case '#' : { DBUG_PUSH(&(argv[i][2])); } break; [...] } } foo = bar_bar_bar(); DBUG_PRINT("bar", ("Foo = %d\n", foo)); foo = blah_blah_blah(); DBUG_PRINT("blah", ("Foo = %d\n", foo)); DBUG_VOID_RETURN(0); } Now, at run-time the program can be called with a command line like 'a.out #d:t mumble'. This is a flag which the DBUG macros use (through DBUG_PROCESS and DBUG_PUSH) to enable and disable various functions. There is tracing, which is an output like >main ->bar_bar_bar -<bar_bar_bar ->blah_blah_blah -<blah_blah_blah <main for simple level tracing. There is also "flag" type printf enabling, where a command line like 'a.out #dbar,:t mumble' would cause all DBUG_PRINTFs with the keyword (1st arg) "bar" to get printed. There are also global enables and disables, including the #define DBUG_OFF, which removes all of the debug code entirely (for production usage). my dbug.h has the following author notice in it, but I think it's outdated. Fred's whereabouts should be easy to determine, if by no other method than eavesdropping on comp.sys.amiga for a while. * AUTHOR * * Fred Fish * (Currently employed by Motorola Computer Division, Tempe, Az.) * hao!noao!mcdsun!fnf * (602) 438-3614 - MM -- passaretti@crd.ge.com {whatever}!crdgw1!brahe!passaret
rosenber@ra.abo.fi (Robin Rosenberg INF) (05/04/90)
>I want to have a DEBUG flag which controls whether diagnostic printfs >are executed or not. I have used the following macros for a while now and they work fine. /* tdebug.h -- tracing & debugging macros * */ #if TDEBUG #define T(s) {dprintf("\033[33m(\033[0m%s\033[0m",#s);{s} dprintf("\033[33m)\033[0m\r\n");} #define D(s) s #define P(a) dprintf a #define V(n,x) {if (debuglevel>=n) dprintf("%s\r\n",x);} #else #define T(s) {s} /* ! trace execution of statements */ #define D(s) ; /* ! execute only when debugging */ #define P(a) /* ! printf when debugging */ #define V1(n,x) {} #endif TDEBUG /* eof */ dprintf has the same synopsis as printf, however if may be some other function. Which function it is is defined at link time. Usually dprintf asks another process to print the debugging info for me. If your system does not allow you to define symbols at link time, replace dprintf with the funtion you want in tdebug.h Note however that the T() macro doesn't work in all cases. Most notably it may have to be written differently for other compilers and may not work if the statement beging traced contains double quotes. Also, the ANSI escape sequences used in the T() macro is to help matching parentheses in the trace output. Here is a sample (not useful) program using these macros #define TDEBUG 1 /* or 0 if debugging is not wanted */ #include "tdebug.h" int debuglevel; main(int argc,char **argv) { debuglevel = atoi(argv[1]); P(("This is a demo. Prog =%s\n",argv[0])); T(subroutine(argc,argv);) V(1,"I will now fall off the e"); } You may use or modify these macros as you like according to your needs. Enjoy! ----------- Robin Rosenberg
travis@cs.columbia.edu (Travis Lee Winfrey) (05/04/90)
In article <40628@cornell.UUCP>, >gordon@mimir.cs.cornell.edu (Jeffrey Adam Gordon) writes: > > I want to have a DEBUG flag which controls whether diagnostic printfs > are executed or not. Well, another variation on the debug macro with two parentheses is to have a first argument that specifies the current level of interest. This argument can be compared with whatever you need: a module-specific #define, a module-specific variable, a global variable. The two biggest problems with this method are the complaints from lint about constants appearing in an if-statement, and that some compilers may not strip out the code when you don't want the output. A sample follow. Note that the numbers here range from 1 to 4 because I define DEBUG on a per-module basis. Some other people specify their interest in debugging information in terms of percentages, i.e., show me 50% of everything you have in this module. that's not intuitive for me. (I'm sorry if anyone else has already described this particular fillip; I looked through all the messages posted so far, as many of the previous posters should have done.) /* * debugging macros. the dprintf macro takes two arguments, a * debugging level (1, 2, 3, 4) and a list of ordinary printf * arguments in parentheses, e.g., * dprintf(1, ("proc_kill_module: sys_ptr is NULL!\n")); * * debugging levels: * level 1: ordinary unexpected events which the programmer may want * to know, but a user will not. all "oh no!" type * information should be marked with this. * level 2: more detailed, usually per-module information that * will a programmer will not want to know *unless* he or * she is debugging that module. * Level 3: more detailed than 2, usually per-procedure * debugging information. debugging statements this * low-level will be removed once gross errors are * found and removed. * Level 4: just a level for demarcating extremely low-level, * usually inner-loop information. removed as level 3 messages. * */ # ifdef DEBUG # define dprintf(dlevel,printfargs) if (dlevel <= DEBUG ) \ printf printfargs # else /* DEBUG */ # define dprintf(a,b) # endif /* DEBUG */ -- Arpa: travis@cs.columbia.edu Usenet: rutgers!columbia!travis
tif@commlab1..austin.ibm.com (/32767) (05/05/90)
In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey Adam Gordon) writes: >I want to have a DEBUG flag which controls whether diagnostic printfs >are executed or not. > DEBUG ("debugging information"); >but then how do I turn DEBUG off? Actually it's easier than you thought: #define DEBUG will turn it off although the string will still be put in your executable (unless your optimizer is better than mine). ("xx") is a parenthesised pointer expression which is a valid C statement. Most people I know of do #define DEBUG(xx) printf xx and then DEBUG(("the flag is %d\n", flag)); The whole thing is completely removed with #define DEBUG(xx) Paul Chamberlain tif@doorstop.austin.ibm.com tif@commlab1.austin.ibm.com sc30661@ausvm6
bjstaff@zds-ux.UUCP (Brad Staff) (05/05/90)
I add some declarations that look something like the following: #ifdef PRODUCTION #define DEBUG 0 #else int DEBUG = FLAG1 | FLAG2 | ... | FLAGn; #endif /* PRODUCTION */ Then I do it like this: if (DEBUG & FLAGx) printf(...); This way the debug statements look more like regular C code, which is more aesthetically pleasing to my eyes. :-) This method allows you to turn debug printfs on and off in a running system by patching the DEBUG variable with a kernel debugger or adb. When you #define PRODUCTION, any compiler worth using (IMHO) will optimize away both the test and the printf itself, for a zero performance penalty. -- Brad Staff | Zenith Data Systems | "A government that can forbid certain 616-982-5791 | psychoactive drugs can mandate others." bjstaff@zds-ux.zds.com | - Russell Turpin
kc@oz.rci.dk (Knud Christensen) (05/07/90)
gordon@mimir.cs.cornell.edu (Jeffrey Adam Gordon) writes: >I want to have a DEBUG flag which controls whether diagnostic printfs >are executed or not. >The obvious way to do this is: >#ifdef DEBUG > printf ("debugging information"); >#endif DEBUG >But its a pain to have to type the #ifdef ... #endif all the time, and >its less readable than simply having: > DEBUG ("debugging information"); >Now, I can use the latter format if I >#define DEBUG printf >but then how do I turn DEBUG off? >I have though of doing the following (which is not very elegant but I >thought it would work): >#ifdef DODEBUG ># define DEBUG printf ># define ENDDEBUG ; >#else ># define DEBUG /* ># define ENDDEBUG */ >#endif DODEBUG >which would allow the following syntax for debugging > DEBUG ("the value is %d", val); ENDDEBUG >Unfortunately, I can't figure out how to #define something to be equal >to "/*" sinece "/*" always seems to be interpreted as the start of a >comment. >Well, I've been rambling trying to describe the problem. Basically, >does anyone have an idea how I can do the above easily and elegantly? >Thanks for reading. >- Jeff > The following, which i found in a magazine solves the problem very elegantly i think: /* debug.h This header file gives a number of usefull definitions for debugging */ #ifdef debug # define DFPRINTF(x) fprintf x # define DTRACE fprintf(stderr, "Trace line %d\n", __LINE__) # define DTRINT(var) fprintf(stderr, "Trace line %d var = %d\n", __LINE__, var) #else # define DFPRINTF(x) # define DTRACE # define DTRINT(var) #endif /* End of debug facility definitions */ C-program #define debug #include "debug.h" int i,j; main() { DFPRINTF((stdout,"This is a test %d", i)); } ---- Knud Christensen RC International, Denmark kc@rci.dk It is better to keep your mouth shut, and look like a fool than to open it, and remove all doubt! - Marx - (Groucho not Karl).
robwah@auto-trol.UUCP (Robert Wahl) (05/08/90)
William Silver writes: >Is there a way to define Debug so that Debug(x, y, z,...) can optionally >either do nothing or generate fprintf(stderr, x, y, z,...) with an >arbitrary number of arguments? Crawford's method still requires >specific mention of stderr in each debug line. Consider the basic setup which is required to use a variable argument list in a macro. The list must be used as the argument list of a function call, and no other arguments can be added. However, that function need not be printf: #ifdef DEBUG #define DPRINTF(list) (dprintf list) #else #define DPRINTF(list) (1) /* Allows use of DPRINTF in expressions */ #endif DPRINTF ((fmtstr, arg1, arg2, arg3)); Writing "dprintf" is left as an exercise for the reader. Using assembly language, it may be an easy thing to prepend stderr to the variable argument list and then call "fprintf". Most likely, though, you will have to parse the format string for the number and type of arguments in order to set up the call to "fprintf". If so, you might as well do it all in C (which at least is portable), and do your output in stages. Here's a simply coded, but dreadfully hacky solution: temporarily replace stdout with stderr, then use printf as suggested before. This is inherently non-portable, inefficient, risky and generates lots of code. #ifdef DEBUG static FILE dprintf_stdout; static int dprintf_retval; #define DPRINTF(list) (dprintf_stdout = *stdout, *stdout = *stderr, \ dprintf_retval = printf list, *stdout = dprintf_stdout), dprintf_retval) #else #define DPRINTF(list) (1) /* Allows use of DPRINTF in expressions */ #endif If you do use this method, forget that you heard of it from me. Perhaps the best solution is just to use fixed argument lists; after all, how many values do you typically output in one debug statement? #ifdef DEBUG #define Debug0(fmt) (fprintf (stderr, fmt)) #define Debug1(fmt,val1) (fprintf (stderr, fmt, val1)) #define Debug2(fmt,val1,val2) (fprintf (stderr, fmt, val1, val2)) ... #else #define Debug0(fmt) (1) #define Debug1(fmt,val1) (1) #define Debug2(fmt,val1,val2) (1) ... #endif Debug3 ("Name is %s, value is %d (0x%x)\n", name, val, val); or Debug1 ("Name is %s, ", name); /* Note lack of newline in format string */ Debug2 ("value is %d (0x%x)\n", val, val); -- Rob Wahl =:-> {robwah@auto-trol.com | ...!ncar!ico!auto-trol|robwah}
fenske@dfsun1.electro.swri.edu (Robert Fenske Jr) (05/08/90)
In article <801@oz.rci.dk> kc@oz.rci.dk (Knud Christensen) writes: >gordon@mimir.cs.cornell.edu (Jeffrey Adam Gordon) writes: > >>I want to have a DEBUG flag which controls whether diagnostic printfs >>are executed or not. > How 'bout this: #define DPRINTF(s) if (DEBUG) printf(s) which can't be used in "if" statements for example--but still useful--or this: #define DPRINTF(s) (DEBUG ? printf(s) : 0) with perhaps some compilers complaining about a useless statement when debug is zero. DEBUG could be a #define or a variable and can be easily taken care of on the compiler command line. -- Robert Fenske, Jr. Sw | The Taming the C*sm*s series: Electromagnetics Division /R---\ | Southwest Research Institute | I | | "The Martian canals were the dfsun1.electro.swri.edu 129.162.160.4 \----/ | Martians' last ditch effort."
robinson (Jim Robinson) (05/09/90)
In article <801@oz.rci.dk> kc@oz.rci.dk (Knud Christensen) writes: >The following, which i found in a magazine solves the problem very elegantly i >think: > >/* > debug.h > > This header file gives a number of usefull definitions for debugging >*/ > >#ifdef debug ># define DFPRINTF(x) fprintf x ># define DTRACE fprintf(stderr, "Trace line %d\n", __LINE__) ># define DTRINT(var) fprintf(stderr, "Trace line %d var = %d\n", __LINE__, var) >#else ># define DFPRINTF(x) ># define DTRACE ># define DTRINT(var) >#endif > >/* > End of debug facility definitions >*/ Isn't the use of __LINE__ non-portable? -- Jim Robinson {uunet,ubc-cs}!van-bc!mdivax1!robinson
guy@auspex.auspex.com (Guy Harris) (05/10/90)
>Isn't the use of __LINE__ non-portable?
The use of __LINE__ is portable to all ANSI C implementations, and to
many non-ANSI C implementations (including most, if not all, UNIX ones).