[comp.lang.c] Funny mistake

wolfram@cip-s05.informatik.rwth-aachen.de (Wolfram Roesler) (02/26/91)

Hello out there,
I had a funny mistake the other day you might be interested in. It was an
obvious syntax error which resulted in legal C code. Funny too how many times
I read over it without seeing whats wrong.

What I wanted to write was:

	if (fct(a,b,c))

but by mistake I wrote:

	if (fct(a,b),c)

Easy to see here, but hard to discover when it's not a b c but some speaking
variable names like NoOfLines or ErrorFlag or FilePtr or something.

Perhaps that's why many people refuse to use speaking variable names... :)

kdq@demott.com (Kevin D. Quitt) (02/27/91)

In article <wolfram.667581530@cip-s05> wolfram@cip-s05.informatik.rwth-aachen.de (Wolfram Roesler) writes:
>Hello out there,
>I had a funny mistake the other day you might be interested in. It was an
>obvious syntax error which resulted in legal C code. Funny too how many times
>I read over it without seeing whats wrong.
>
>What I wanted to write was:
>
>	if (fct(a,b,c))
>
>but by mistake I wrote:
>
>	if (fct(a,b),c)
>
>Easy to see here, but hard to discover when it's not a b c but some speaking
>variable names like NoOfLines or ErrorFlag or FilePtr or something.
>
>Perhaps that's why many people refuse to use speaking variable names... :)


    This is why god invented prototypes.


-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

ckp@grebyn.com (Checkpoint Technologies) (02/27/91)

In article <wolfram.667581530@cip-s05> wolfram@cip-s05.informatik.rwth-aachen.de (Wolfram Roesler) writes:
>What I wanted to write was:
>
>	if (fct(a,b,c))
>
>but by mistake I wrote:
>
>	if (fct(a,b),c)

Well, if fct had had a non-varadic prototype in scope, then the compiler
would have rejected it.  If it had had a varadic prototype (variable
number of arguments) then you still would be in bad luck.

Lint would have warned you about it if c were actually a constant
expression.

Otherwise, yep, that's one of the curves C can throw.
-- 
First comes the logo: C H E C K P O I N T  T E C H N O L O G I E S      / /  
                                                                    \\ / /    
Then, the disclaimer:  All expressed opinions are, indeed, opinions. \  / o
Now for the witty part:    I'm pink, therefore, I'm spam!             \/

larry@st-andy.uucp (Larry Martell) (03/13/91)

In article <wolfram.667581530@cip-s05> wolfram@cip-s05.informatik.rwth-aachen.de (Wolfram Roesler) writes:
>Hello out there,
>I had a funny mistake the other day you might be interested in. It was an
>obvious syntax error which resulted in legal C code. Funny too how many times
>I read over it without seeing whats wrong.
>
>What I wanted to write was:
>
>	if (fct(a,b,c))
>
>but by mistake I wrote:
>
>	if (fct(a,b),c)
>
It's not a syntax error - it is leagl C code. If it were a syntax error
it wouldn't compile.
-- 
Larry Martell
uunet!st-andy!larry
212-668-9478

antek@binoc.tamu.edu (Antek Laczkowski) (03/14/91)

>>I had a funny mistake the other day you might be interested in. 
>>What I wanted to write was:
>>	if (fct(a,b,c))
>>but by mistake I wrote:
>>	if (fct(a,b),c)

Hell, I have no idea what "fct" is for; but that remains me my mistakes, 
a VERY hard to catch one, because the string (see below) is still perfect 
C code (like that above - no SYNTAX error there!) : 

"if (a = b)" instead of "if (a == b)". 

That's a REALLY disgusting error, 
because the "C" compiler (at least under UNIX BSD 3.4) doesn't report it, 
and the effect is to set "a" to be "b" and the "if" behaves depending of
the value of "b" - well, I can't blame the compiler, it thinks, my idea is
"set a to be b and check, what the value is" - but at least "lint" should 
point it as a possible source of errors. If you have 10000 lines of code and
1000 "ifs" inside, "searching" for "=" or for "if" can make you happy.
A debugger is better - but still... I'm carefull now, but anyway, it happens.

The goal of this post is to point out this particular kind of error, not
to tell everyone around how good in "C" I am - I'm not very good :)

Antek @ Bioch.Tamu.Edu ("reply" won't work - that's a new UNIX system!)

av@uta.fi (Arto V. Viitanen) (03/14/91)

In article <13337@helios.TAMU.EDU> antek@binoc.tamu.edu (Antek Laczkowski) writes:
>
>"if (a = b)" instead of "if (a == b)". 
>
>That's a REALLY disgusting error, 
>because the "C" compiler (at least under UNIX BSD 3.4) doesn't report it, 

It seems, that almost all PC C compilers (at least Turbo C, C++) reports this
kind of stuff.



-- 
Arto V. Viitanen				         email: av@kielo.uta.fi
University Of Tampere,				   	    av@ohdake.cs.uta.fi
Finland

stan@Dixie.Com (Stan Brown) (03/15/91)

>Hell, I have no idea what "fct" is for; but that remains me my mistakes, 
>a VERY hard to catch one, because the string (see below) is still perfect 
>C code (like that above - no SYNTAX error there!) : 

>"if (a = b)" instead of "if (a == b)". 

>That's a REALLY disgusting error, 
>because the "C" compiler (at least under UNIX BSD 3.4) doesn't report it, 
>and the effect is to set "a" to be "b" and the "if" behaves depending of

	Some compilers will report this as a suspicous occurence.  The
	one I think I remember this on is Zortech, but I have yet to
	see a UNIX compiler complain about it,  The lint on my mchine
	doesn't complain eithe.  I wonder if anybody's does ?


-- 
Stan Brown	P. c. Design 	404-363-2303	Ataant Ga.
(emory|gatech|uunet) rsiatl!sdba!stan				"vi forever"

jtc@motcad.portal.com (J.T. Conklin) (03/16/91)

In article <8148@rsiatl.Dixie.Com> stan@Dixie.Com (Stan Brown) writes:
>>"if (a = b)" instead of "if (a == b)". 
>
>	Some compilers will report this as a suspicous occurence.  The
>	one I think I remember this on is Zortech, but I have yet to
>	see a UNIX compiler complain about it,  The lint on my mchine
>	doesn't complain eithe.  I wonder if anybody's does ?

Gimpel's FlexeLint:
     if (a = b)
     foo.c  5  Info 720: Boolean test of assignment


-- 
J.T. Conklin    jtc@motcad.portal.com, ...!portal!motcad!jtc

gwyn@smoke.brl.mil (Doug Gwyn) (03/16/91)

In article <8148@rsiatl.Dixie.Com> stan@Dixie.Com (Stan Brown) writes:
>>"if (a = b)" instead of "if (a == b)". 
>... I have yet to see a UNIX compiler complain about it

That's good, because it is valid C and the compiler cannot know whether
or not it reflects the programmer's intentions.

gsh7w@astsun.astro.Virginia.EDU (Greg Hennessy) (03/17/91)

#>>"if (a = b)" instead of "if (a == b)". 
#>... I have yet to see a UNIX compiler complain about it

Doug Gwyn:
#That's good, because it is valid C and the compiler cannot know whether
#or not it reflects the programmer's intentions.

Then perhaps that is why having an optional flag to inform the user of
this sometimes suspicious code fragment may be a good idea.



--
-Greg Hennessy, University of Virginia
 USPS Mail:     Astronomy Department, Charlottesville, VA 22903-2475 USA
 Internet:      gsh7w@virginia.edu  
 UUCP:		...!uunet!virginia!gsh7w

bill@camco.Celestial.COM (Bill Campbell) (03/17/91)

In <15481@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:

>In article <8148@rsiatl.Dixie.Com> stan@Dixie.Com (Stan Brown) writes:
>>>"if (a = b)" instead of "if (a == b)". 
>>... I have yet to see a UNIX compiler complain about it

>That's good, because it is valid C and the compiler cannot know whether
>or not it reflects the programmer's intentions.

My personal preferance would be a WARNING message.  Certainly it
is a legal construction, but 90% of the time when I do this it
was my mistake!  I'm not perfect and I would like the compiler to
point out places where it is likely that I didn't do something
right.

I usually avoid this particular construction simply because every
time I look at it at some later date I will have to figure out
whether I did it right in the first place :-)

Bill
-- 
INTERNET:  bill@Celestial.COM   Bill Campbell; Celestial Software
UUCP:   ...!thebes!camco!bill   6641 East Mercer Way
             uunet!camco!bill   Mercer Island, WA 98040; (206) 947-5591

gwyn@smoke.brl.mil (Doug Gwyn) (03/17/91)

In article <1991Mar16.195153.15509@murdoch.acc.Virginia.EDU> gsh7w@astsun.astro.Virginia.EDU (Greg Hennessy) writes:
-#>>"if (a = b)" instead of "if (a == b)". 
-#>... I have yet to see a UNIX compiler complain about it
-Doug Gwyn:
-#That's good, because it is valid C and the compiler cannot know whether
-#or not it reflects the programmer's intentions.
-Then perhaps that is why having an optional flag to inform the user of
-this sometimes suspicious code fragment may be a good idea.

In the world of UNIX, we normally rely on "lint" to generate warnings
about *possible* problems like this.  The compilers are expected to
accept conforming translation units and silently translate them.

rainer@boulder.Colorado.EDU (Rainer Malzbender) (03/18/91)

I believe my Datalight (Zortech) compiler actually issues a warning if you
say "if(a=b)", something like "possible unintended assignment". This actually
helped me out a few times, but I've since switched to MSC6.0.

--
Rainer Malzbender, PhD  "It's not the bullet that kills you, it's the hole."
Dept. of Physics (303)492-6829                             -Laurie Anderson
U. of Colorado, Boulder         rainer@boulder.colorado.edu 128.138.240.246

roy%cybrspc@cs.umn.edu (Roy M. Silvernail) (03/18/91)

rainer@boulder.Colorado.EDU (Rainer Malzbender) writes:

> I believe my Datalight (Zortech) compiler actually issues a warning if you
> say "if(a=b)", something like "possible unintended assignment". This actually
> helped me out a few times, but I've since switched to MSC6.0.

Turbo also issues "Possibly incorrect assignment" for constructs like
'if(x=get_key())...'. I don't think I've ever used 'if(a=b)', but I often
code assignments like the first example above. Makes more sense to me
than 'x=get_key();if(x)...'.
--
Roy M. Silvernail --  roy%cybrspc@cs.umn.edu - OR-  cybrspc!roy@cs.umn.edu
  perl -e '$x = 1/20; print "Just my \$$x! (adjusted for inflation)\n"'
        [space reserved for clever quote]{mail your submissions}

karln@uunet.uu.net (03/19/91)

In article <2372@kielo.uta.fi> av@kielo.uta.fi (Arto V. Viitanen) writes:
>In article <13337@helios.TAMU.EDU> antek@binoc.tamu.edu (Antek Laczkowski) writes:
>>
>>"if (a = b)" instead of "if (a == b)". 
>>
>>That's a REALLY disgusting error, 
>>because the "C" compiler (at least under UNIX BSD 3.4) doesn't report it, 
>
>It seems, that almost all PC C compilers (at least Turbo C, C++) reports this
>kind of stuff.
>

	Is not this supposed to be a job for lint? Both ARE valid syntax ...

	Karl Nicholas

	karln!karln@uunet.uu.net

Sepp@ppcger.ppc.sub.org (Josef Wolf) (03/20/91)

roy%cybrspc@cs.umn.edu (Roy M. Silvernail) writes:
] rainer@boulder.Colorado.EDU (Rainer Malzbender) writes:
] > I believe my Datalight (Zortech) compiler actually issues a warning if you
] > say "if(a=b)", something like "possible unintended assignment".
] Turbo also issues "Possibly incorrect assignment" for constructs like
] 'if(x=get_key())...'.

Do you really want this? Do you really want the compiler crying every
time you write something like the following (just an example)

while ( get_data (...) && (p = malloc (...))) {
  ...
}

well, you could write something like

while (get_data (...)) {
  p = malloc (...);
  if (!p)
    break;
  ...
}

but the first one seems to be more clearly to me...

Greets
    Sepp

| Josef Wolf, Germersheim, Germany | +49 7274 8047  -24 Hours- (call me :-)
| ...!ira.uka.de!smurf!ppcger!sepp | +49 7274 8048  -24 Hours-
|     sepp@ppcger.ppc.sub.org      | +49 7274 8967  18:00-8:00, Sa + Su 24h
|  "is there anybody out there?"   | all lines 300/1200/2400 bps 8n1

campbell@redsox.bsw.com (Larry Campbell) (03/20/91)

In article <8148@rsiatl.Dixie.Com> stan@Dixie.Com (Stan Brown) writes:
->Hell, I have no idea what "fct" is for; but that remains me my mistakes, 
->a VERY hard to catch one, because the string (see below) is still perfect 
->C code (like that above - no SYNTAX error there!) : 
-
->"if (a = b)" instead of "if (a == b)". 
-
-	Some compilers will report this as a suspicous occurence.  The
-	one I think I remember this on is Zortech, but I have yet to
-	see a UNIX compiler complain about it,  The lint on my mchine
-	doesn't complain eithe.  I wonder if anybody's does ?

Under SVR4:

    /home/campbell> cat test.c
    #include <stdio.h>
    
    void foo(int a, int b)
    {
        if (a = b)
            (void) printf("yow!\n");
    }
    /home/campbell> lint -u test.c
    (5) warning: assignment operator "=" found where "==" was expected
    
    set but not used in function
        (3) a in foo

I think the lint that comes with it is itself reason enough to run SVR4.
-- 
Larry Campbell             The Boston Software Works, Inc., 120 Fulton Street
campbell@redsox.bsw.com    Boston, Massachusetts 02109 (USA)

rob@array.UUCP (Rob Marchand) (03/20/91)

In article <15490@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>In article <1991Mar16.195153.15509@murdoch.acc.Virginia.EDU> gsh7w@astsun.astro.Virginia.EDU (Greg Hennessy) writes:
>-#>>"if (a = b)" instead of "if (a == b)". 
>-#>... I have yet to see a UNIX compiler complain about it
>-Doug Gwyn:
>-#That's good, because it is valid C and the compiler cannot know whether
>-#or not it reflects the programmer's intentions.
>-Then perhaps that is why having an optional flag to inform the user of
>-this sometimes suspicious code fragment may be a good idea.
>
>In the world of UNIX, we normally rely on "lint" to generate warnings
>about *possible* problems like this.  The compilers are expected to
>accept conforming translation units and silently translate them.

	There are several PD tools laying about that will catch this sort
	of thing, and print a warning.  As I understand it, they are 
	documented in one of the Nutshell Handbooks (hmm, Using Lint,
	or some such, by Ian Darwin?), which (I believe) include listings
	of the source code.  The source is also available in the 
	nutshell/lint subdirectory on uunet for anon. ftp.  I also have
	the stuff if anyone wants a copy.  No guarantees as to how well
	they work, etc.   Your mileage may vary.

	Cheers!
	Rob Marchand
-- 
Rob Marchand                   UUCP  : uunet!attcan!lsuc!array!rob
Array Systems Computing        ARPA  : rob%array.UUCP@uunet.UU.NET
401 Magnetic Drive, Unit 24    Phone : +1(416)736-0900   Fax: (416)736-4715
Downsview, Ont CANADA M3J 3H9  Telex : 063666 (CNCP EOS TOR) .TO 21:ARY001

scott@bbxsda.UUCP (Scott Amspoker) (03/20/91)

In article <525@bria> uunet!bria!mike writes:
>[ in regards to the expression "if (a = b)" instead of "if (a == b)" ]
>
>Think *lint*.  IMHO, there is nothing we need less than a compiler spitting
>out more useless verbage.

The only problem with that is that many PC based C compilers don't include
a lint program.  It makes sense that the programmer at least have the option
of enabling various warning messages.  Strangely enough, I once comitted
the exact opposite mistake.  I had a C statement like this:

	    i == j;

The compiler (bless its little heart) gave me the warning:

	"code has no effect"


-- 
Scott Amspoker                       | Touch the peripheral convex of every
Basis International, Albuquerque, NM | kind, then various kinds of blaming
(505) 345-5232                       | sound can be sent forth.
unmvax.cs.unm.edu!bbx!bbxsda!scott   |    - Instructions for a little box that
                                     |      blurts out obscenities.

rickc@telly.on.ca (Rick Copley) (03/21/91)

In article <1991Mar15.180449.13100@motcad.portal.com> jtc@motcad.portal.com (J.T. Conklin) writes:
>In article <8148@rsiatl.Dixie.Com> stan@Dixie.Com (Stan Brown) writes:
>>>"if (a = b)" instead of "if (a == b)". 
>>
>>	Some compilers will report this as a suspicous occurence.  The
>>	one I think I remember this on is Zortech, but I have yet to
>>	see a UNIX compiler complain about it,  The lint on my mchine
>>	doesn't complain eithe.  I wonder if anybody's does ?
>
>Gimpel's FlexeLint:
>     if (a = b)
>     foo.c  5  Info 720: Boolean test of assignment
>
>
>-- 
>J.T. Conklin    jtc@motcad.portal.com, ...!portal!motcad!jtc


The following program on an NCR Tower SYS 5r3 (AT&T based) system produces
"2 and 2 are equal" when executed and lint procudes no complaints at all.

main()
{
  int a, b;

  a = 1;
  b = 2;

  if (a = b)
    (void)printf("%d and %d are equal\n", a, b);

  return(0);
}

I will try this program at home with my MCS 5.1 compiler with the /W3 option
and see what it says, and get back to ya.

rickc@telly.on.ca

-- 
#include <sys/types.h>
main()
{
  typedef long lotsa;
  lotsa *fun;
  time_t in;
  fun = (lotsa)hack(in);
}

henry@zoo.toronto.edu (Henry Spencer) (03/21/91)

In article <15490@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>In the world of UNIX, we normally rely on "lint" to generate warnings
>about *possible* problems like this.  The compilers are expected to
>accept conforming translation units and silently translate them.

Actually, in the world of UNIX this is a pervasive myth.  Even in the
world of UNIX, the compilers generate warnings for excessively-suspicious
constructs.  They just don't go as far in that direction as some more
modern compilers.
-- 
"[Some people] positively *wish* to     | Henry Spencer @ U of Toronto Zoology
believe ill of the modern world."-R.Peto|  henry@zoo.toronto.edu  utzoo!henry

gwyn@smoke.brl.mil (Doug Gwyn) (03/21/91)

In article <1991Mar20.173511.3904@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
>Even in the world of UNIX, the compilers generate warnings for
>excessively-suspicious constructs.

Only for outright violations of the language specification,
not for what are now known as strictly conforming programs.

gsh7w@astsun8.astro.Virginia.EDU (Greg Hennessy) (03/21/91)

>>"if (a = b)" instead of "if (a == b)". 
>>... I have yet to see a UNIX compiler complain about it

Me:
#>-Then perhaps that is why having an optional flag to inform the user of
#>-this sometimes suspicious code fragment may be a good idea.

Doug Gwyn:
#>In the world of UNIX, we normally rely on "lint" to generate warnings
#>about *possible* problems like this.  The compilers are expected to
#>accept conforming translation units and silently translate them.

Well,
1) I said optional flag, so the person who wants silent complations of
their strictly conforming programs get it, and the person who wants
warning can have that also.

2) Experiance has shown that having lint seperate from the compiler
means that many people would not use it.

I would sugguest that compilers should do lint (after setting a flag)
as part of their function.

I know for a fact that many would disagree.


--
-Greg Hennessy, University of Virginia
 USPS Mail:     Astronomy Department, Charlottesville, VA 22903-2475 USA
 Internet:      gsh7w@virginia.edu  
 UUCP:		...!uunet!virginia!gsh7w

hargrove@theory.tn.cornell.edu (Paul H. Hargrove) (03/21/91)

In article <15529@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>In article <1991Mar20.173511.3904@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
>>Even in the world of UNIX, the compilers generate warnings for
>>excessively-suspicious constructs.
>
>Only for outright violations of the language specification,
>not for what are now known as strictly conforming programs.


And the AIX C compiler which has chosen to take on lint's responsibilities.
But that's IBM for you: If there's a perfectly good tool available, then
rewrite it and stick a copyright on your version.

Paul H. Hargrove | hargrove@theory.tn.cornell.edu | I said what?

volpe@camelback.crd.ge.com (Christopher R Volpe) (03/21/91)

In article <15529@smoke.brl.mil>, gwyn@smoke.brl.mil (Doug Gwyn) writes:
|>In article <1991Mar20.173511.3904@zoo.toronto.edu>
henry@zoo.toronto.edu (Henry Spencer) writes:
|>>Even in the world of UNIX, the compilers generate warnings for
|>>excessively-suspicious constructs.
|>
|>Only for outright violations of the language specification,
|>not for what are now known as strictly conforming programs.

I wouldn't mind having warnings for suspicious yet strictly conforming
constructs. Especially if I could do:

#pragma SHUT_UP
if (temp=var1)
  printf("func(%d) is %d\n",temp,func(&var1));
else
  printf("Value is zero! Cannot apply function. Aborting...\n");
#pragma OK_TO_NAG
      
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

scott@bbxsda.UUCP (Scott Amspoker) (03/21/91)

In article <1991Mar21.021504.25553@murdoch.acc.Virginia.EDU> gsh7w@astsun8.astro.Virginia.EDU (Greg Hennessy) writes:
>Doug Gwyn:
>#>In the world of UNIX, we normally rely on "lint" to generate warnings
>#>about *possible* problems like this.  The compilers are expected to
>#>accept conforming translation units and silently translate them.
>
>Well,
>1) I said optional flag, so the person who wants silent complations of
>their strictly conforming programs get it, and the person who wants
>warning can have that also.
>[...]
>I would sugguest that compilers should do lint (after setting a flag)
>as part of their function.
>
>I know for a fact that many would disagree.

Well I'm not one of them.  I agree completely.  I see no reason to
run a source file through lint prior to the C compiler everytime I
make a change when I could enable certain desireable warning messages
(of mistakes I frequently make) within the compiler.

-- 
Scott Amspoker                       | Touch the peripheral convex of every
Basis International, Albuquerque, NM | kind, then various kinds of blaming
(505) 345-5232                       | sound can be sent forth.
unmvax.cs.unm.edu!bbx!bbxsda!scott   |    - Instructions for a little box that
                                     |      blurts out obscenities.

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/22/91)

In article <1991Mar21.021504.25553@murdoch.acc.Virginia.EDU> gsh7w@astsun8.astro.Virginia.EDU (Greg Hennessy) writes:
> 2) Experiance has shown that having lint seperate from the compiler
> means that many people would not use it.

On the other hand, I was quite annoyed the first time I used gcc -Wall
that it still bothered producing an object file... cc and lint belong
together as much as cat and cat -t.

---Dan

scm3775@tamsun.tamu.edu (Sean Malloy) (03/22/91)

>Well I'm not one of them.  I agree completely.  I see no reason to
>run a source file through lint prior to the C compiler everytime I
>make a change when I could enable certain desireable warning messages
>(of mistakes I frequently make) within the compiler.
>
On the machine I use, someone up high decided that it would be easier to
write a shell script than to modify the compilers...  You'll have to make
some mods (more than likely) but the following script works just fine IMHO.

----------------------------- cut here -------------------------------------

#!/bin/sh
PATH=/bin:/usr/bin
#ident	"@(#)ctrans:CC	1.7.3.1"

#NOTE: To properly use the CC command you should check the values of the
#following variables to be sure they are set to the locations of the
#appropriate translator files on your system.
#
#CCROOTDIR set to directory containing cfront c++filt and patch/munch
#CCLIBDIR set to directory containing the C++ libraries
#I set to directory containing C++ header files

CCROOTDIR=${CCROOTDIR-/usr/local/att_c++/bin}
CCLIBDIR=${CCLIBDIR-/usr/local/att_c++/lib}
I=${I-/usr/local/att_c++/include}

#Option passed to cc to tell linker to look for libraries in another
#directory.  Set it to -L if -Wl,-L doesn't work.
LOPT=-L

trap 'rm -fr $TEMPDIR; exit' 1 2 3 15

#	main makefile will set PM_FLAG to MUNCH (default) or PATCH
PM_FLAG=PATCH

DEMANGLE=${DEMANGLE-1}	# set to 0 to disable linker output demangling

if test "$CCROOTDIR" != "" ;then
	CCROOTDIR="$CCROOTDIR/"
fi

LIB_ID=${LIB_ID-C}
LIBRARY=${LIBRARY--l${LIB_ID}}
cfrontC=${cfrontC-${CCROOTDIR}cfront}

if test "$PM_FLAG" = "PATCH"
then
	patchC=${patchC-${CCROOTDIR}patch}
else
	munchC=${munchC-${CCROOTDIR}munch}
	NM=${NM-nm}
	NMFLAGS=${NMFLAGS-}
fi

cplusfiltC=${cplusfiltC-${CCROOTDIR}c++filt}
ccC=${ccC-cc}
cppC=${cppC-/lib/cpp}

if test "$CCLIBDIR" = "/usr/lib"
then LLIBPATH=""
else LLIBPATH="$LOPT$CCLIBDIR"
fi

#sys.fix will set SYS to the designated system
#it will then be defined for each CC invocation
SYS=-DBSD

#For Ansi compatibility, c_plusplus => __cplusplus
#For backward compatibility, retain c_plusplus for 2.0
CPLUS=-Dc_plusplus=1
cPLUS=-D__cplusplus=1

TMPDIR=${TMPDIR-"/usr/tmp"}
TEMPDIR=$TMPDIR/CC.$$
C= EE=0 FON= XON= O=
PON= R= SUF= X= Y= DASHR= PLUSI= STRIP=
Z= E=0 OF= P=
NOLOAD= NLO=
AFAIL=0
OO="a.out"
ISUF=".c"
MVLIST=
APASS=0
defmem=D deflist=

rm -fr $TEMPDIR
mkdir $TEMPDIR
E=$?
if test $E -ne 0
then
     echo "CC: error:can not create temporary directory in $TEMPDIR: stop" 1>&2
     exit $E
fi
for A do
	case $A in
	-Yp,*)	cppC=`expr $A : '-Yp,\(.*\)'`/`basename ${cppC}`
		X="$X $A"
		;;
	-YI*)	X="$X $A"
		;;
	-Y*)	Z="$Z $A"
		;;
	+S)	echo "CC: +S no longer accepted (ignored)"
		;;
	+V)	echo "CC: +V no longer accepted (ignored)"
		;;
	+i)	PLUSI=1
		;;
	-s)	STRIP=1
		;;
	+x)	XON=1
		;;
	+*)	O="$O $A"
		;;
	-E)	PON=1
		;;
	-F)	FON=1
		;;
	-Fc)	FON=1
		O="$O +L"
		;;
	-C)	Y="$Y $A"
		;;
	-S*)	NOLOAD=".s"
		NLO="$A"
		;;
	-P)	NOLOAD=".i"
		NLO="-P"
		;;
	-c*)	NOLOAD=".o"
		NLO="-c"
		;;
	-I*) 	if test "$A" != "-I" 
		then
                  	Y="$Y $A"
		else
			ION=1
                fi
		;;
	-D*)	eval $defmem='"$A"'
		deflist="$deflist \"\$$defmem\""
		defmem=${defmem}x
		;;
	-U*)	Y="$Y $A"
		;;
	-p)	P="-p"
		;;
	-r)	DASHR=1
		Z="$Z $A"
		;;
	-o*)	if test "$A" != "-o" 
		then
			OO=`expr $A : '-o\(.*\)'`
                  	A="-o $OO"
		else
			OX=1
                fi
		APASS=1
		OF="$OF $A"
		Z="$Z $A"
		;;
	-.c)	echo "bad suffix option: -.c" 1>&2
		;;
	-.*)	SUF=`expr "$A" : '-\(.*\)'`
		;;
	*.[Cc]) if	test -f $A
		then

			case $A in
				*.c) B=`basename $A .c` ;;
				*.C) B=`basename $A .C` ;;
			esac

			if	test $PON
			then
				if test $SUF
				then
					echo "$cppC $O  $A > $B$SUF:" 1>&2
					eval '$cppC' '$Y' $deflist '$CPLUS' '$cPLUS' '$SYS' '-I$I'  '$A' >'$B$SUF'
					E=$?
				else
					eval '$cppC' '$Y' $deflist '$CPLUS' '$cPLUS' '$SYS' '-I$I'  '$A'
					E=$?
				fi
				case $E in
				0)	;;
				*)	AFAIL=1; break
					;;
				esac
			elif	test $FON
			then
				if test $SUF
				then
					echo "$cfrontC $O  $A > $B$SUF:" 1>&2
					eval '$cppC' -C '$Y' $deflist '$CPLUS' '$cPLUS' '$SYS' '-I$I'  '$A' >$TEMPDIR/cpptmp
					E=$?
					if test $E -ne 0
					then
						echo "CC: cpp failure: $E" 1>&2
						AFAIL=1; break
					fi
					$cfrontC +L +f$A $O <$TEMPDIR/cpptmp >$B$SUF
					E=$?
				else	
					eval '$cppC' -C '$Y' $deflist '$CPLUS' '$cPLUS' '$SYS' '-I$I'  '$A' >$TEMPDIR/cpptmp
					E=$?
					if test $E -ne 0
					then
						echo "CC: cpp failure: $E" 1>&2
						AFAIL=1; break
					fi
					$cfrontC +L +f$A $O <$TEMPDIR/cpptmp 
					E=$?
				fi
				case $E in
				0)	;;
				*)	AFAIL=1; break
					;;
				esac
			else
				echo "CC $O $A:" 1>&2
				eval '$cppC' -C '$Y' $deflist '$CPLUS' '$cPLUS' '$SYS' '-I$I'  '$A' >$TEMPDIR/cpptmp
				E=$?
				if test $E -ne 0
				then
					echo "CC: cpp failure: $E" 1>&2
					AFAIL=1; break
				fi
				$cfrontC +L +f$A $O <$TEMPDIR/cpptmp >$TEMPDIR/$B$ISUF
				E=$?
				R=1
				C="$C $TEMPDIR/$B$ISUF"
				case $E in
				0)	X="$X $B$ISUF"
					if test "$NOLOAD" != ".c" 
					then
						Z="$Z $TEMPDIR/$B.o"
					fi
					MVLIST="$MVLIST $B"
					APASS=1
					;;
				127)    echo "Too many compilation errors" 1>&2
					AFAIL=1
					;;
				999)	echo "CC argument error" 1>&2
					AFAIL=1
					;;
				1)	echo "1 error" 1>&2
					AFAIL=1
					;;
				*)	echo "$E errors" 1>&2
					AFAIL=1
					;;
				esac
			fi
		else
			echo "$A not found" 1>&2
			EE=1
		fi
		;;
	*.i)    if test -f $A
		then

			if test $PON
			then
				echo "CC -E $A incompatible: ignoring $A" 1>&2
	        	else
				if test $FON
				then
					eval '$cppC' -C '$Y' $deflist '$CPLUS' '$cPLUS' '$SYS' '-I$I'  '$A' >$TEMPDIR/cpptmp
					if test $? -ne 0
					then
						echo "CC: cpp failure: $E" 1>&2
						AFAIL=1; break
					fi
					$cfrontC +L +f$A $O <$TEMPDIR/cpptmp 
					if test $? -ne 0
					then
						AFAIL=1
					fi
  				else	
					B=`basename $A .i`
					echo "CC $O $A:" 1>&2
					$cfrontC +L +f$A $O < $A > $TEMPDIR/$B$ISUF
					E=$?
					R=1
					C="$C $TEMPDIR/$B$ISUF"
					case $E in
					0)	X="$X $B$ISUF"
						if test "$NOLOAD" != "-c" 
						then
							Z="$Z $TEMPDIR/$B.o"
						fi
						MVLIST="$MVLIST $B"
						APASS=1
						;;
					*)	AFAIL=1
						;;
				esac
				fi
			fi

		else
			echo "$A not found" 1>&2
			EE=1
		fi
		;;
	*.s)	# add to list to be compiled in $TEMPDIR, set flag to go on
		B=`basename $A .s`
		X="$X $B.s"
		cp $A $TEMPDIR/$B.s
		APASS=1

		if test "$NOLOAD" != "-c" 
		then
			# add object entry to the load list
			Z="$Z $TEMPDIR/$B.o"
		fi
		;;
	*)	if test $XON
		then	
			O="$O +x$A"
			XON=""
		elif test $ION
		then
			Y="$Y -I$A"
			ION=""
		else
			Z="$Z $A"
			if test $OX
			then
				OO=$A
				OF="$OF $A"
				OX=""
			else
				X="$X $A"
			fi
		fi
 		APASS=1 # setting APASS to 1 causes link step to execute
		;;
	esac
done

case $APASS in
0)	;;
*)					# generate code
	if test "$PLUSI"		#leave ..c's lying around
	then
        	#remove #line's from the ..c's for sdb
		for f in $C
		do
			sed "/^#/d" $f >$TEMPDIR/temp
			mv $TEMPDIR/temp $f 2> /dev/null
		done
	fi
	
	#if one file failed in cpp or cfront then do not create a.out
	if test $AFAIL -eq 1
	then
		if test -z "$NOLOAD"
		then
			NOLOAD=".o"
			NLO="-c"
                fi
        fi 

        if test "$NOLOAD"
        then
 		# make sure there are some .c, .s, or .i files in X
 		ANY_CS=`expr "$X" : '.*\(\.[CcSsi]\).*'`
 		if test "$ANY_CS"
 		then
 			echo "$ccC $P $NLO $X" 1>&2
   			# contortions to cope with bug handling path in cc
   			(cd $TEMPDIR; $ccC $P $NLO $X)		# compile, no load
 			EE=$?
   			if test $EE = 0
   			then
 				# move products back into current directory
   				mv $TEMPDIR/*$NOLOAD . 2> /dev/null
   			fi
 		fi
	else
		echo "$ccC $P $LLIBPATH $OF $X $LIBRARY" 1>&2
  		(cd $TEMPDIR; $ccC $P -c $X)			# compile, no load
		EE=$?
		case $EE in
		0) # load
			$ccC $P $LLIBPATH $Z $LIBRARY >$TEMPDIR/__err 2>&1
			EE=$?
			(test $DEMANGLE = 1 &&
			 $cplusfiltC <$TEMPDIR/__err 2>/dev/null) ||
			cat $TEMPDIR/__err

			if test $EE = 0  -a "$DASHR" != 1
			then	#find ctors/dtors
				case $PM_FLAG in
				PATCH)
					$patchC $OO
					EE=$?
					;;
				*)
					CTDT=__ctdt$$
					TCTDT=${TEMPDIR}/${CTDT}
					$NM $NMFLAGS $OO | \
						$munchC $P > ${TCTDT}.c
					$ccC -c ${TCTDT}.c && \
						$ccC $P $LLIBPATH ${CTDT}.o $Z $LIBRARY
					EE=$?
					rm ${CTDT}.o
					;;
				esac
				if test "$STRIP"
				then
					strip $OO
				fi
			fi
                        COUNT=0 
                        for A in $X
                        do 
                           COUNT="`expr $COUNT + 1`"
                        done
                        if test $COUNT -gt 1
                        then
                           mv $TEMPDIR/*.o . 2> /dev/null
                        fi
			;;
		esac
	fi
esac

if test "$R"
then
   if test "$PLUSI"
   then
 	for A in $MVLIST
 	do
 		mv $TEMPDIR/$A${ISUF} $A.${ISUF} 2> /dev/null
 	done
   fi
fi

rm -fr $TEMPDIR

if test $AFAIL -ne 0
then
	exit $AFAIL
fi

case $E in
0)	exit $EE
	;;
*)	exit $E
esac

-------------------------------------- cut here -------------------------------

-Sean

/*--------------------------------------------------------------------------*\
| Sean C. Malloy    | x041sc@tamuts.tamu.edu  |   No one ever expects the    |
| (409) 764-0699    | scm3775@tamsun.tamu.edu |        SPANISH INQUISITION!  |
\*__________________________________________________________________________*/

byron@archone.tamu.edu (Byron Rakitzis) (03/22/91)

In article <15490@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>In article <1991Mar16.195153.15509@murdoch.acc.Virginia.EDU> gsh7w@astsun.astro.Virginia.EDU (Greg Hennessy) writes:
>-#>>"if (a = b)" instead of "if (a == b)". 
>-#>... I have yet to see a UNIX compiler complain about it
>-Doug Gwyn:
>-#That's good, because it is valid C and the compiler cannot know whether
>-#or not it reflects the programmer's intentions.
>-Then perhaps that is why having an optional flag to inform the user of
>-this sometimes suspicious code fragment may be a good idea.
>
>In the world of UNIX, we normally rely on "lint" to generate warnings
>about *possible* problems like this.  The compilers are expected to
>accept conforming translation units and silently translate them.

Flame on:

I think it's time that compilers assumed a greater responsibility in this
direction. How many people remember to run lint on their code? How many do
it at the last minute? I think that one of the best features of gcc is
the -Wall flag; I compile all my code this way, and it has saved my rear
end at compile time countless times.

A "responsible" compiler will flag this if-business as a warning. However,
this will no longer be an ANSI compiler in the Gwynian sense. It will be a
hand-holding compiler that goes out of its way to detect possible glitches in
the code, but if done tastefully, I think it could promote better coding
style in a way that lint has completely failed to do.

I have had uniformly bad experience with lint. Not only is it an outdated
tool (I have not seen an ansi lint) but many of its warnings are not
pertinent to the code. For example, the "pointer alignment" problem with
every call to malloc, and the "returns a value which is ignored" problem
with every call to printf. A user of lint must wade through a whole bunch
of garbage error messages to evaluate whether the code really needs fixing.
And adding gratuitous casts to void before every printf is a solution that's
worse than the problem, IMHO.

I am presently writing (at a snail's pace, unfortunately) a compiler which
will operate at two levels: "pedantic-mode" (the *default*) where it will
try to be picky (in a reasonable way) about both departures from standard
C and from "normal" coding practises (assignments in if statements are on
the verge of obfuscated C, in my opinion; a human reading the code some
time later has to check very thoroughly to make sure that it is in fact
not a typo); and "silent-mode" in which case all warnings are turned off.

The UNIX many-tools philosophy has its uses (I *AM* a many-tools fan), but
I do not think that lint has a place in that toolchest. For one, the
language that a particular compiler implements is rarely the same language
that a tool like lint thinks its checking (cf. the ANSI problem). I
strongly believe it is up to the compiler to take care about safeguarding
the use of the language which it translates, even if this means flagging
valid code which has been *probably* erroneously typed in.

Flame off.

pmoore@hemel.bull.co.uk (Paul Moore) (03/22/91)

what seems to be needed is a compiler that will generater a warning about
	if(a=b)
(lets own up here, we have all made this mistake at one time or another , I got
so paranoid about this recently that I ended up writing
	while((a==getchar())!=EOF)
Try fixing that one - and no compiler ever complains about "possible unintended
non assignment")

To stop the compiler moaning about perfectly good code how about a "yes I know
there's an = instead of ==" pragama. Ie

#pragma nowarn
	if(a=b)

The pragma just applies to the next statement
-- 
!---------------------------------------------------------------!
! Paul Moore, Bull HN UK, Maxted Rd,Hemel Hempstead, HP2 7DZ.   !
! Phone:(44) 442 232222  Fax:(44) 442 234084			!	
! pmoore@hemel.bull.co.uk     "a smile, a song and a core dump" !
!---------------------------------------------------------------!

henry@zoo.toronto.edu (Henry Spencer) (03/23/91)

In article <1991Mar21.021504.25553@murdoch.acc.Virginia.EDU> gsh7w@astsun8.astro.Virginia.EDU (Greg Hennessy) writes:
>2) Experiance has shown that having lint seperate from the compiler
>means that many people would not use it.

More to the point, with the (important) exception of intermodule consistency
checking, the notion that doing lintish checking in the compiler costs a lot
extra is a *myth*.  The compiler already has almost all the information it
needs to do most of lint's checks; it merely needs to pay attention to what
it already knows.  There needs to be a way to shut it up, since suspicious-
looking constructs are sometimes legitimate, but there's just no good reason
why a compiler shouldn't do most of that checking routinely.
-- 
"[Some people] positively *wish* to     | Henry Spencer @ U of Toronto Zoology
believe ill of the modern world."-R.Peto|  henry@zoo.toronto.edu  utzoo!henry

henry@zoo.toronto.edu (Henry Spencer) (03/23/91)

In article <15529@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>>Even in the world of UNIX, the compilers generate warnings for
>>excessively-suspicious constructs.
>
>Only for outright violations of the language specification,
>not for what are now known as strictly conforming programs.

Depends on which UNIX world we are talking about. :-)  Real, live warnings
about suspicious but legal constructs are not unknown.
-- 
"[Some people] positively *wish* to     | Henry Spencer @ U of Toronto Zoology
believe ill of the modern world."-R.Peto|  henry@zoo.toronto.edu  utzoo!henry

gwyn@smoke.brl.mil (Doug Gwyn) (03/23/91)

In article <1778@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
>Well I'm not one of them.  I agree completely.  I see no reason to
>run a source file through lint prior to the C compiler everytime I
>make a change when I could enable certain desireable warning messages
>(of mistakes I frequently make) within the compiler.

Compiler options for lint-like warnings are fine with me,
so long as they are normally suppressed.  However, "lint"
does things that compilers normally do not, such as
checking external linkages against definition files.

gwyn@smoke.brl.mil (Doug Gwyn) (03/23/91)

In article <13584@helios.TAMU.EDU> byron@archone.tamu.edu (Byron Rakitzis) writes:
>I have had uniformly bad experience with lint. Not only is it an outdated
>tool (I have not seen an ansi lint) but many of its warnings are not
>pertinent to the code. For example, the "pointer alignment" problem with
>every call to malloc, and the "returns a value which is ignored" problem
>with every call to printf. A user of lint must wade through a whole bunch
>of garbage error messages to evaluate whether the code really needs fixing.
>And adding gratuitous casts to void before every printf is a solution that's
>worse than the problem, IMHO.

Rather than fighting "lint", it is much more productive to learn how
to exploit it.

(1)  I have heard that SVR4 includes, for the first time in the official
UNIX distribution, both an ANSI-conforming (at least that's the intent)
C implementation AND a corresponding version of "lint".

(2)  There are several solutions to the malloc() "pointer alignment"
warning, which I agree is a drawback to traditional "lint".  Some versions
of lint() support additional comment-flags that can be attached to lint-
library definitions to indicate malloc()-like, or printf()-like interfaces.
Or, your application can deal with this directly, for example as we did in
the MUVES implementation, whose memory-manager interface header contains
kludges like:
	#ifdef lint	/* shut "lint" up */
	#define MmVReallo( o, n, t )	\
		((void)MmDebug( (n) + (int)sizeof(t) ), o)
	#else
	#define MmVReallo( o, n, t )	\
		((t *)Mm_RAllo( (pointer)(o), (n) * (unsigned)sizeof(t) ))
	#endif
Or, you could just learn to live with the handful of additional spurious
warnings, so long as you check each of them out to be SURE that it is due
to "lint"'s lack of knowledge about malloc()'s special properties.

(3)  "Returns a value which is ignored" is a legitimate warning in most
cases (i.e. those where a failure of the function is reflected in its
returned value).  This is certainly true for printf(), which CAN FAIL
and therefore should have its return value checked in robust applications.
Much of the time, the value of functions such as strcpy() is not of much
use (although I personally make frequent use of it), so in those cases it
would be useful for "lint" to support some comment-flag on the definition;
I don't know if this particular flag is supported by any versions of
"lint", but it certainly could be.

(4)  Anyone who simply adds a bunch of (void) casts to existing code has
missed the boat.  The time to consider whether or not it is necessary to
examine the value returned by a given function invocation is WHEN THE
CODE IS BEING WRITTEN.  Use of (void) there serves as a definition note
that the programmer has considered the issue and decided that it is safe
to ignore that specific return value.  If you follow such a procedure,
then ANY "returns a value which is ignored" warning from "lint" indicates
a genuine error, or at least a programmer oversight.

>I strongly believe it is up to the compiler to take care about safeguarding
>the use of the language which it translates, even if this means flagging
>valid code which has been *probably* erroneously typed in.

Actually, if a compiler flags such code of MINE, it is *probably* the
compiler that has made the mistake.  I really don't appreciate C
compilers that cater to novices at the expense of experts.  Options to
turn on "novice mode" are okay, but they MUST be OPTIONS.

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (03/23/91)

In article <13584@helios.TAMU.EDU>, byron@archone.tamu.edu (Byron Rakitzis) writes:
> Flame on:
Whooossshhhhh....
> I have had uniformly bad experience with lint.  [...] [M]any of its
> warnings are not pertinent to the code.  For example, the "pointer
> alignment" problem with every call to malloc, and the "returns a
> value which is ignored" problem with every call to printf.

As someone else pointed out, printf can fail.  Nonetheless, I agree
with you - the level of robustness that calls for error-checking every
call to printf is seldom called for.

What I did was to write a wrapper for lint that chucks complaints based
on egrep patterns (kept in ~/.lintx).  My list of patterns, for example:

^ioctl, arg. 3 used inconsistently
^malloc, arg. 1 used inconsistently
returns value which is always ignored$
returns value which is sometimes ignored$
^argvec used(.*), but not defined$
#include of /usr/include/... may be non-portable$

the last one being due to an idiocy in Sun's cpp, and the next-to-last
because nobody (yet :-) seems to agree with me about argvec/argcnt.

> Flame off.
...ssshhhhh *snik*

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

campbell@redsox.bsw.com (Larry Campbell) (03/25/91)

In article <1991Mar21.021504.25553@murdoch.acc.Virginia.EDU> gsh7w@astsun8.astro.Virginia.EDU (Greg Hennessy) writes:
-
-2) Experiance [sic] has shown that having lint seperate [sic] from the compiler
-means that many people would not use it.

Having lint separate from the compiler means we can use lint to check our
code for all platforms, regardless of how benighted their compilers are.  We
ship code on five platforms, none of which are UNIX.  Yet we keep our master
source libraries in RCS on a UNIX box, for two reasons:  RCS and lint,
neither of which have decent equivalents on the platforms we build products
for.

Around here, it is considered *extremely* bad form to check code in to RCS
that hasn't passed lint.
-- 
Larry Campbell             The Boston Software Works, Inc., 120 Fulton Street
campbell@redsox.bsw.com    Boston, Massachusetts 02109 (USA)

mcdaniel@adi.com (Tim McDaniel) (03/26/91)

I will insert my usual plug for Gimpel Software's FlexeLint.  It can
support ANSI C and many old C dialects, and you can turn on or off any
of the 300-odd messages on a message-by-message basis, or only for
certain identifiers, and can turn them on or off via in-line comments.
Call +1 215 584 4261 (in Collegeville, Pennsylvania).  I have no
financial or other stake in their success, except for being a
satisfied customer hoping for more releases.  8-)

--
   "Of course he has a knife.  We all have knives.  It's 1183, and we're
   all barbarians."
Tim McDaniel                 Applied Dynamics Int'l.; Ann Arbor, Michigan, USA
Internet: mcdaniel@adi.com                UUCP: {uunet,sharkey}!amara!mcdaniel