Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!spool.mu.edu!snorkelwacker.mit.edu!hsdndev!cmcl2!adm!smoke!gwyn From: gwyn@smoke.brl.mil (Doug Gwyn) Newsgroups: comp.lang.c Subject: Re: Efficient STRing CoMPares? Message-ID: <15496@smoke.brl.mil> Date: 17 Mar 91 03:02:49 GMT References: <1991Mar15.142821@mars.mpr.ca> <15486@smoke.brl.mil> <1193@caslon.cs.arizona.edu> Organization: U.S. Army Ballistic Research Laboratory, APG, MD. Lines: 33 In article <1193@caslon.cs.arizona.edu> dave@cs.arizona.edu (Dave Schaumann) writes: >|#define StrEq( a, b ) (*(a) == *(b) && strcmp( a, b ) == 0) /* UNSAFE */ >By "unsafe", I assume you mean it will likely crash on a NULL pointer. No, I mean that it is an "unsafe function-like macro", meaning that its arguments will be evaluated other than once each, unlike the situation for a genuine function invocation. This is something that the user of the macro needs to be aware of. I take it for granted that a null pointer should not be provided as an argument to a function expecting an object pointer, unless it is specifically advertised as doing something useful in that case. >Also, if you tend to compare equal successfully a lot, this will actually >be slower. In most applications, comparing unequal would be far more frequent. This optimization is a win in almost all situations, even when the compiler generates in-line code for strcmp(). (Note, however, that one release of Gould's UTX-32 C compiler generated bad code if an argument to StrEq() was a string literal; the base registers got used up unnecessarily. I think this was fixed in a later release.) If you happen to know that there is at least one character before the terminator in each string, you can further optimize: #define StrEq1( a, b ) (*(a) == *(b) && strcmp( (a) + 1, (b) + 1 ) == 0) /* UNSAFE */ However, I prefer the first form, which works wherever strcmp() does, so long as the multiple evaluation of its arguments is not an issue.