[net.lang.c] Equality vs Assignment

kpk@gitpyr.UUCP (09/17/86)

Who among us has not been bitten at least once by writing

if (x = 1) ...

when he/she meant

if (x == 1)

What I want to know is

Has anyone written a program to scan a C program and issue a warning message
for those lines where an assignment has occured in a conditional statement
(i.e. if, while, the third statement in a for loop)?

If anyone has written such a program, why not post it (or at least mail me a
copy)?

To any yacc and lex hacks: why not see if you can whip up such a program?

rbutterworth@watmath.UUCP (Ray Butterworth) (09/18/86)

> Who among us has not been bitten at least once by writing
> if (x = 1) ...
> when he/she meant
> if (x == 1)
> What I want to know is
> 
> Has anyone written a program to scan a C program and issue a warning message
> for those lines where an assignment has occured in a conditional statement
> (i.e. if, while, the third statement in a for loop)?

There is already such a program:  lint.
Here's the modified section you want from the BSD 4.2 version of
/usr/src/usr.bin/lint/lpass1.c.

contx( p, down, pl, pr ) register NODE *p; register *pl, *pr; {

    *pl = *pr = VAL;
    if (p->in.type==UNDEF) down=VAL; /* (void) cast */

    switch( p->in.op ){

    case NOT:
        *pl=down;
    case ANDAND:
    case OROR:
        if (hflag&&(p->in.right->in.op==ASSIGN))
            werror("Possible unintended assignment");
    case QUEST:
        *pr = down;
    case CBRANCH:
        if (hflag&&(p->in.left->in.op==ASSIGN))
            werror("possible unintended assignment");
        break;

    case SCONV:
    case PCONV:
    ...

cg@myrias.UUCP (Chris Gray) (09/18/86)

The proper place for this check is of course as a warning issued by the C
compiler. It's not all that hard - it took me about 30 lines of code in the
compiler (ANSI draft based) that I've done. It's a check I felt was quite
important, since I've been bitten by it too many times (I program in other
languages besides C, where '=' IS a comparison).

		Chris Gray (...alberta!myrias!cg)

caesar@ge-dab.UUCP (Robert J. Caesar Jr.) (09/21/86)

I don't have a programs, but this might help as a future solution.
In the project I am involved with, we use:

#define is    ==
#define isn_t !=

This has helped us avoid a lot of headaches. The code reads a
little easier too.

if (x is 1)

if (y isn_t x)


-- 
   Bob Caesar                   
   General Electric SCSD                      caesar@static.dab.ge.com 
   PO Box 2500 Room 4336                      (904) 258-3043 
   Daytona Beach, Florida 32015            ...!mcnc!ge-rtp!ge-dab!caesar

Eliel@smoke.UUCP (09/24/86)

This is a good question, although I think that for CMS/SP users, using yacc
or lex may be a bit overboard when XEDIT provides the "all" command that
would let one easily scan for that kind of error.  I suppose that a macro
to do this before compiling would be easy to write.  As I don't have time
right now, let me outline what I mean:
    in CW EXEC :
         "XEDIT "fn ft/* h or c */" (PROFILE chk_equ"
          if rc ^= 0 then exit /* flag indicating desire to continue or no*/
          else CW ....
    chk_equ XEDIT would have something like this :
         "all /for/ && /=/ "
            some search code...
         "all /while/ && /=/ "
            some more..., etc, etc.
Let me know if any one has the time to do it so that I can get a copy!

also, if any one knows of versions of yacc and/or lex for the CMS/SP environ-
ment, please let me know as well!
   have a day,
             eliel

brett@wjvax.UUCP (Brett Galloway) (09/25/86)

In article <270@myrias.UUCP> cg@myrias.UUCP (Chris Gray) writes:
>The proper place for this check is of course as a warning issued by the C
>compiler. It's not all that hard - it took me about 30 lines of code in the
>compiler (ANSI draft based) that I've done. It's a check I felt was quite
>important, since I've been bitten by it too many times (I program in other
>languages besides C, where '=' IS a comparison).

I disagree; the proper place for this check is NOT as a warning issued by
the compiler.  "if(var=value)" is a perfectly valid, supported, and documented
construction, endorsed by K & R et al.  The fact that it is misleading is
an artifact of the ambiguity of the meaning of "equal" and "=".  In any
event, it is a well-defined and supported feature of the language.  It is
ridiculous for the compiler to bark on the expression (var=value) when it
happens to fall into the context of a simple if().

The proper place for this check is within lint, whose purpose is to

	... detect features of ... [C programs] ... which are likely
	to be bugs, or non-portable, or wasteful.

				- lint(1), from 4.2 BSD manual

Further, it should be a special test by lint, invoked by a special argument,
so that those of us who like to use lint don't have to listen to the
warning forever.

-- 
-------------
Brett Galloway
{pesnta,twg,ios,qubix,turtlevax,tymix,vecpyr,certes,isi}!wjvax!brett