Efficient STRing CoMPares?

Doug Gwyn gwyn at smoke.brl.mil
Sun Mar 17 13:02:49 AEST 1991


In article <1193 at caslon.cs.arizona.edu> dave at 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.



More information about the Comp.lang.c mailing list