das@eplunix.UUCP (David Steffens) (04/04/91)
When beginning maintenance activities on code that someone else has written,
the first thing I do is to run lint on the code to see what pops out.
This time, lint failed to find something that I think it should have.
Try the following on your favorite flavor of lint. The first four if's
generate "variable may be used before set" complains as expected.
The fifth if statement does not. I think it should. If not, why not??
Tested on 4.2bsd, 4.3bsd, SunOS4.0.3, SunOS4.1 and RTU5.0 (SysV variant).
main()
{
int foo;
int *bar, *blap, *flap;
int baz[10];
if (foo == 0)
printf("Yikes!\n");
if (bar == 0)
printf("Egads!\n");
if (*blap == 0)
printf("Gadzooks!\n");
if (flap[2] == 0)
printf("Ack!\n");
if (baz[2] == 0)
printf("Eh?\n");
exit(0);
}
--
David Allan Steffens | I believe in learning from past mistakes...
Eaton-Peabody Laboratory | ...but does a good education require so many?
Mass. Eye & Ear Infirmary, 243 Charles Street, Boston, MA 02114
{harvard,mit-eddie,think}!eplunix!das (617) 573-3748 (1400-1900h EST)
michi@ptcburp.ptcbu.oz.au (Michael Henning) (04/04/91)
das@eplunix.UUCP (David Steffens) writes: >Try the following on your favorite flavor of lint. The first four if's >generate "variable may be used before set" complains as expected. >The fifth if statement does not. I think it should. If not, why not?? >Tested on 4.2bsd, 4.3bsd, SunOS4.0.3, SunOS4.1 and RTU5.0 (SysV variant). >main() >{ > int foo; > int *bar, *blap, *flap; > int baz[10]; > if (foo == 0) > printf("Yikes!\n"); > if (bar == 0) > printf("Egads!\n"); > if (*blap == 0) > printf("Gadzooks!\n"); > if (flap[2] == 0) > printf("Ack!\n"); > if (baz[2] == 0) > printf("Eh?\n"); > exit(0); >} The reason is that 'baz' is an array, and lint cannot check whether an individual array element has been initialized, since that cannot always be figured out at compile time. The net effect is that you *never* get a warning if you use an array element that is not initialized. In contrast, 'flap' is pointer which is not initialized at the time it is first used, so you *do* get a warning. The fact that you are indexing of the pointer has nothing to do with it, you get the same warning if you replace the fourth test with if (flap == 0) printf("Ack!\n"); Michi. -- -m------- Michael Henning +61 75 950255 ---mmm----- Pyramid Technology +61 75 522475 FAX -----mmmmm--- Research Park, Bond University michi@ptcburp.ptcbu.oz.au -------mmmmmmm- Gold Coast, Q 4229, AUSTRALIA uunet!munnari!ptcburp.oz!michi
suitti@ima.isc.com (Stephen Uitti) (04/05/91)
In article <380@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au (Michael Henning) writes: >das@eplunix.UUCP (David Steffens) writes: > >>Try the following on your favorite flavor of lint. >>main() >>{ >> int baz[10]; >> if (baz[2] == 0) >> printf("Eh?\n"); >> exit(0); >>} > >The reason is that 'baz' is an array, and lint cannot check whether an >individual array element has been initialized, since that cannot always >be figured out at compile time. The net effect is that you *never* get >a warning if you use an array element that is not initialized. It could try, and in this case, it sure can. The 'baz' array is a stack variable, with local scope. If baz[] wasn't initialized within the curly braces, it wasn't initialized. SysV lint (maybe others) complain that main() may return a random value to the environment - so maybe "return 0;" would be better. With ANSI C, exit() is essentially part of the language, so maybe lint could be better. Traditional 'lint' uses the 'pcc' parser. Great. If 'pcc' didn't care, then 'lint' can't derive the information. What have you saved? Many C compilers, 'pcc' included, have poor exception handling. How often have you gotten "Syntax error" when the compiler should have known that it got "foo" when expecting one of a small number of tokens? I've worked with compilers that tell you what they expected. Once you get used to it, it is extraordinarily helpful. Our friend 'lint', says "Syntax error" too. Lint belongs in the compiler, anyway. Turbo C generates considerably more complete checking during compilation than 'lint' ever did, at over 3,000 lines per minute on a 7 MHz 8088 Pc/xt. Stephen. suitti@ima.isc.com "We Americans want peace, and it is now evident that we must be prepared to demand it. For other peoples have wanted peace, and the peace they received was the peace of death." - the Most Rev. Francis J. Spellman, Archbishop of New York. 22 September, 1940
dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (04/05/91)
In <1991Apr04.212837.13505@ima.isc.com> suitti@ima.isc.com (Stephen
Uitti) writes:
Lint belongs in the compiler, anyway. Turbo C generates
considerably more complete checking during compilation than 'lint'
ever did, at over 3,000 lines per minute on a 7 MHz 8088 Pc/xt.
Turbo C does good intrafile checking. However, lint really shines when
it does interfile checking. Until we get smarter (and slower) linkers,
we will have to rely upon lint and similar programs for this. A
compiler that did interfile checking would essentially be a linker.
Properly created headers can help the compiler do some of what lint
does, but then who checks the headers? Lint, of course.
--
Rahul Dhesi <dhesi@cirrus.COM>
UUCP: oliveb!cirrusl!dhesi
gwyn@smoke.brl.mil (Doug Gwyn) (04/06/91)
In article <1991Apr04.212837.13505@ima.isc.com> suitti@ima.isc.com (Stephen Uitti) writes: >With ANSI C, exit() is essentially part of the language, so maybe >lint could be better. And indeed some versions of "lint" ARE better. >Traditional 'lint' uses the 'pcc' parser. Great. If 'pcc' >didn't care, then 'lint' can't derive the information. That's not entirely accurate, even for pre-ANSI C "lint". There are several utilities within the "software generation system" that share source code, but each of them tends to have its own special pieces of support within the shared code. (I think it was "ctrace" that I decided to also bring into the fold rather than giving it its own slightly edited version of the SGS sources as it was shipped with SVR2.) >I've worked with compilers that tell you what they expected. >Once you get used to it, it is extraordinarily helpful. Our >friend 'lint', says "Syntax error" too. Yes, such diagnostics as you mentioned are nice. The generic "syntax error" style of message is often due to the use of a parser generator (such as "yacc") with insufficient care given to its error-reporting and -recovery capabilities. At least the SVR2 "lint" and PCC recover from syntax errors considerably better than some other implementations I've seen, wherein the least little typo produces literally hundreds of spurious subsequent diagnostics. (Might as well make the first diagnostic fatal in such a case!) >Lint belongs in the compiler, anyway. No, I disagree. SYNTAX CHECKING is perhaps best done by a genuine compiler, but that is NOT the only task that "lint" performs. In particular, "lint" is used to check for nonportabilities, possible unintended but valid C usage, intermodule linkage compatibility, and so forth, none of which would I WANT a C compiler to do. The compiler should correctly and SILENTLY translate a correct program to efficient code, not try to second-guess the programmer.
harrison@necssd.NEC.COM (Mark Harrison) (04/07/91)
In article <1059@eplunix.UUCP>, das@eplunix.UUCP (David Steffens) writes: > When beginning maintenance activities on code that someone else has written, > the first thing I do is to run lint on the code to see what pops out. > This time, lint failed to find something that I think it should have. Gimpel's Flexelint catches it. I *LIKE* flexelint. } FlexeLint (U32) Ver. 4.00h, Copyright Gimpel Software 1985-1990 } foo.c 7 Warning 530: foo (line 3) not initialized } foo.c 9 Warning 530: bar (line 4) not initialized } foo.c 11 Warning 530: blap (line 4) not initialized } foo.c 13 Warning 530: flap (line 4) not initialized } foo.c 15 Warning 530: baz (line 5) not initialized } foo.c 18 Warning 533: Return mode of main inconsistent with line 1 PS, you forgot to return a value from main(). :-) :-) :-) -- Mark Harrison harrison@ssd.dl.nec.com (214)518-5050 {necntc, cs.utexas.edu}!necssd!harrison standard disclaimers apply...
das@eplunix.UUCP (David Steffens) (04/13/91)
In article <755@necssd.NEC.COM>, harrison@necssd.NEC.COM (Mark Harrison) says: > Gimpel's Flexelint catches it. Of course the _line numbers_ in your sample bear little resemblance to reality (picky, picky). Did you alter the code? Or the output sample? Snide Aside: Just what I need... another "awk: bailing out near line 1" :-) > I *LIKE* flexelint. So might I... assuming the line numbers it produces are _correct_ ! Where can I get it and approximately how much does it cost? -- David Allan Steffens | I believe in learning from past mistakes... Eaton-Peabody Laboratory | ...but does a good education require so many? Mass. Eye & Ear Infirmary, 243 Charles Street, Boston, MA 02114 {harvard,mit-eddie,think}!eplunix!das (617) 573-3748 (1400-1900h EST)