One more point regarding = and == (more flamage)

Blair P. Houghton bhoughto at hopi.intel.com
Fri Mar 29 20:58:32 AEST 1991


In article <11563 at dog.ee.lbl.gov> torek at elf.ee.lbl.gov (Chris Torek) writes:
>function of the number and placement of characters typed).  Typographial
>errors take three forms:
>
>	transpositions	(`The quick bronw fox jumps over hte lazy dog')
>	insertions	(`The quiick brown fox jumpsd over the lazy dog')
>	deletions	(`The quick brown fox umps over the lazy dog')

	replacements	(`The quick brown fox jumps ovwr the lazy dog')

>Keeping these in mind, let us consider C code.

Consideration noted.

When dealing with ~45,000 lines of code (it's over there,
on the Apollo, compiling...) I don't bother with statistics;
I use egrep.  Just tonight, in fact, I found a `==' that had
accidentally been typed as `=', just by typing

	egrep 'display[ 	]*=' *.[ch]

Thirty seconds from suspicion to fix, and I didn't have to
go looking for `!=0' to do it...

>I must consider this a `red flag' signifying a possible error, while
>
>	if ((a = b) != 0)

It's still nothing more than redundant.  Where's the
explanation?  I still don't know what a and b are doing in
that conditional in the first place.  I'd really rather see
a comment that mentions that this is an assignment that
tests, plus what's being assigned and tested, than that
contentless, crufty, explicit comparison with zero.

I have a key on my vt220 programmed with a vi(1) macro
(and labeled in pencil) which echoes thusly:

	oif ()^M^T/* true */^[k$i

and when in vi types (here, I'll do it now):<shift><F13>
if (and I start typing here)
    /* true */

So the first thing ever I see after typing the expression is
that the next line wants a comment, and the first thing I
type in that comment is what "true" means, like
if ( a = b )
    /* a and b are non-null; list b exists; append to list */
    a->next = ...

I couldn't care less whether the equals was right; all
it tells me is _how_ you chose the true path; if I can't
tell _why_ you chose it I'll dress you down in a hurry. if
I _can_ tell why you chose it I can tell you the optimal
way to choose it and how you nearly optimal is your method
of choosing.  (This one isn't on its face; it should be
if ( b )
    /* b non-null; list exists; copy holder and append dingus */
    a = b;
    a->next = ...

So the next question to ask is, Did I need `a' later regardless
of the test?  Hey! Look! Context-sensitivity! Who would've thunk it?)

>  * Embedded assign-and-test is common enough not to get rechecked.

It is by any experienced maintainer.  Take,

	egrep '\([^!(=]*=[^=)]*\)' *.[ch]

for instance.  Running this on ~/src/*.[ch] produced:

loghist.c:    for ( i = 0; i < n_slots; i++ )
rna.c:#define	hour(x)	( ((x)<=0||(x)>=24) ? 12   : ( (x)>12 ? (x)-12 : (x) ) )
rna.c:    if ( (af = fopen(accf,"r")) == NULL ) {
rna.c:	if ( tms->tm_hour >= a->onhr && tms->tm_hour < a->offhr ) {
toupper.c:    while ( (int) (c = getchar()) != EOF )
udkeys.c:	    if ( (n = atoi ( s+1 )) > 5 && n < 20 )

Lookitthat.  5000 lines of code produce exactly three
assign-and-tests, and one of them is a test against -1,
while another is tested against 5, and one is testing
fopen() to see if it _is_ NULL...

Seems it isn't all that common, after all, even among
those of us who tend to use such things blithely...

(Some pretty cool tools there, btw... rna, in fact -- and you'll
find this _really_ hard to believe -- prevents me from running
rn during work hours... :-) It works, too.  I see that polite
"You are prohibited..." message and I just clear the screen
and go back to crashing my Apollo...)

>	if (a = b)			/* oops */
>		n == f(n);		/* oops */
>
>both of which draw warnings from many compilers.

And a few hundred comp.lang.c readers, it seems...

				--Blair
				  "C'mon, machine, link those puppies!"



More information about the Comp.lang.c mailing list