[comp.lang.c] "str*cmp

guy@auspex.auspex.com (Guy Harris) (05/04/91)

 >> } >   if (show_to && strncmp(p, login, strlen(login)))
 >
 >> My copy says !strncmp(p, login, strlen(login)) ....
 >
 >Ooops.  Finger trouble.  So does mine.

Perhaps this is a hint that one shouldn't treat "strncmp()" as if it
were a Boolean function, and should instead compare its result with 0
explicitly, e.g. if you're comparing strings for equality, use "=="?

ronald@robobar.co.uk (Ronald S H Khoo) (05/04/91)

guy@auspex.auspex.com (Guy Harris) writes:

>  >> My copy says !strncmp(p, login, strlen(login)) ....
>  >Ooops.  Finger trouble.  So does mine.
 
> Perhaps this is a hint that one shouldn't treat "strncmp()" as if it
> were a Boolean function, and should instead compare its result with 0
> explicitly, e.g. if you're comparing strings for equality, use "=="?

I must admit that the !strncmp() construct which appears all over the
code is one of the things that I find very hard to follow.  If I need to
understand a piece of the code, I tend to rewrite it as == 0 first
before looking at it :-).  But, it's *their* code, which I'm grateful
for, so I ain't going to complain about it.  Guy's right that I can't
read !strcmp, but I wasn't actually complaining about it, just noting
that I had seen or copied it wrong originally.
-- 
Ronald Khoo <ronald@robobar.co.uk> +44 81 991 1142 (O) +44 71 229 7741 (H)

wjc@hos1cad.ATT.COM (Bill Carpenter) (05/05/91)

guy> Perhaps this is a hint that one shouldn't treat "strncmp()" as if
guy> it were a Boolean function, and should instead compare its result
guy> with 0 explicitly, e.g. if you're comparing strings for equality,
guy> use "=="?

Since most of the time I'm using str*cmp() in a Boolean way anyhow,
and since I used to frequently get the sense of the test reversed, I
almost always do it as a macro now:

 #define EQSTR(a,b)    ((a) && (b) && (*(a) == *(b)) && !strcmp((a),(b)))
 #define EQSTRN(a,b,n) ((a) && (b) && (*(a) == *(b)) && !strncmp((a),(b),(n)))

Of course, these are a little elaborate and have side-effects, so you
could stick with the simpler

 #define EQSTR(a,b)    (!strcmp((a),(b)))
 #define EQSTRN(a,b,n) (!strncmp((a),(b),(n)))

(especially if you enjoy dereferenced nulls as much as I do :-).
-- 
  Bill Carpenter         att!hos1cad!wjc  or  attmail!bill

scc@rlgvax.Reston.ICL.COM (Stephen Carlson) (05/07/91)

In article <7609@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
>
> >> } >   if (show_to && strncmp(p, login, strlen(login)))
> >
> >> My copy says !strncmp(p, login, strlen(login)) ....
> >
> >Ooops.  Finger trouble.  So does mine.
>
>Perhaps this is a hint that one shouldn't treat "strncmp()" as if it
>were a Boolean function, and should instead compare its result with 0
>explicitly, e.g. if you're comparing strings for equality, use "=="?

I prefer to set up the following macros:

#define streq !strcmp
#define strneq !strncmp

This way I can use streq() as a normal boolean-type function; that is, I can
use it bare in conditionals or with the logical negation '!', and it still makes
sense.  Compare,

	if (!strcmp("foo", "bar")) ...
with
	if (streq("foo", "bar")) ...

The latter is understandable at a glance; I wish I could say the same for
the former.  When I happen to care whether a string is greater than another,
I would use strcmp() with an explicit test:

	if (strcmp("foo", "bar") > 0) ...

Comments anyone?  Especially regarding streq's alternative definition:

#define streq(s,t) (strcmp((s), (t)) == 0)

Is it more kosher to define streq as a macro with two arguments rather than
one without any arguments?

-- 
Stephen Carlson           | ICL OFFICEPOWER Center    | In theory, theory and
scc@rlgvax.reston.icl.com | 11490 Commerce Park Drive | practice are the same.
..!uunet!rlgvax!scc       | Reston, VA  22091         |    (703) 648-3300

martin@mwtech.UUCP (Martin Weitzel) (05/08/91)

In article <1991May7.012817.4395@rlgvax.Reston.ICL.COM> scc@rlgvax.Reston.ICL.COM (Stephen Carlson) writes:

>#define streq !strcmp
>#define strneq !strncmp

What about:

#define strdiff strcmp
#define strndiff strncmp

	if (strdiff("foo", "bar") == 0) /* if there is no difference ... */

	if (!strdiff("foo", "bar"))	/* if there is no difference ... */

	if (strdiff("foo", "bar"))	/* if there IS a difference ... */

The nice thing with this approach is that you can almost blindly convert
any source which does NOT use this style: %s/\<strcmp\>/strdiff/g.

The other nice thing is that, after you get tired of changing the sources
written by others, sooner or later your eyes and brains get trained simply
to READ any "strcmp" you encounter as "strdiff" ...

(There's also a minor nitpick with the solution of the original poster:
"*neq" tastes slightly as "not equal" to some programmers. I admit that
"*ndiff" could also be misinterpreted in this way, but IMHO "neq" has
made it into some computer languages, "ndiff" hasn't.)
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83