gurulet aptitude test (and bug)
mcdaniel at uicsrd.csrd.uiuc.edu
mcdaniel at uicsrd.csrd.uiuc.edu
Sun Dec 11 10:40:00 AEST 1988
I'm not a Gwyn/Torek/Harris-level guru, but I'll give it a shot.
Written 6:38 pm Dec 8, 1988 by jpa at celerity.UUCP in comp.lang.c:
> Please don't send me mail to tell me what the problem is
^^^
I count 12 problems with the code. I suppose that the basis of the
problem is that the code was
> a contrived example
(as you put it) and was not linted.
Actually, not all the problems are "bugs" per se; some are just bad
style. In this list, "struct zztop {" is designated line 1:
I The program has no side-effects; a "decent" optimizer should
dead-code the entire program. :-) However, a "decent" compiler
wouldn't compile this program at all.
II Line 4: the declaration of "struct zztop" was probably meant to
have a ";" after the closing "}". Without it, sub1()'s return
type is "struct zztop":
struct zztop {int a; int b;} sub1() {...}
With a ";", sub1()'s return type is an int. This point is
irrelevant, really, since sub1's return value is always ignored.
III Line 5 is an comment, but what it says is obvious from
inspection. Comments like
i++; /* Increment i */
ought to be avoided. OK, I'll admit this one is reaching pretty
far . . . :-)
IV Line 10, "zz.a = 0x77777777;", is non-portable. If "int"s are
16 bits long, the result of assigning 0x77777777 (presumably a
long) to the int zz.a is implementation-defined.
V Line 12: sub1() is declared above as returning a value.
However, no "return" statement is ever used in sub1(). It's not
a bug because the return value of sub1() is never used.
However, if a function doesn't return a value, I prefer to
declare it "void".
VI Line 13 has the first bug. Line 11 implies that sub2 is a
function of one argument (a struct zztop) returning int. Line
13 defines sub2 as a function of NO arguments, returning int.
I'm not surprised that a coredump occurs.
VII Line 16 is like line 10 (unportable to 16-bit machines).
VIII Line 17: parentheses are no longer needed following "return".
Some always use them, some don't. I don't. It's more or less a
religious issue.
IX Line 17: sub2() returns 0x77777777, but sub2()'s return type is
int. This will fail on 16-bit machines.
X sub2()'s return value is always ignored.
XI Line 22: the other unequivocal bug. Above, sub1 was defined as
a function returning int but taking no arguments. Here, one
argument is passed in.
XII The program does not "exit()", nor does "main" return with a
value. On some systems, that means that the program exits with
an undefined exit status, which is probably non-zero. If this
program were invoked in a Bourne-shell script under "set -e", or
C-shell using "csh -e", the shell script would abort. Always
use "exit(expression)", or use "return expression;" in main().
Lint picks up many of these problems:
lint -phbxac bug.c
bug.c:
bug.c(10): warning: long assignment may lose accuracy
bug.c(16): warning: long assignment may lose accuracy
bug.c(17): warning: long assignment may lose accuracy
sub2: variable # of args. bug.c(14) :: bug.c(11)
sub1: variable # of args. bug.c(8) :: bug.c(22)
sub1 value is used, but none returned <<< 1
sub2 returns value which is always ignored
_iob used( llib-port(25) ), but not defined <<< 2
The messages marked "1" and "2" are spurious, but the rest are fine.
--
Tim, the Bizarre and Oddly-Dressed Enchanter
Center for ||| Internet, BITNET: mcdaniel at uicsrd.csrd.uiuc.edu
Supercomputing ||| UUCP: {uunet,convex,pur-ee}!uiucuxc!uicsrd!mcdaniel
Research and ||| ARPANET: mcdaniel%uicsrd at uxc.cso.uiuc.edu
Development, ||| CSNET: mcdaniel%uicsrd at uiuc.csnet
U of Illinois ||| DECnet: GARCON::"mcdaniel at uicsrd.csrd.uiuc.edu"
More information about the Comp.lang.c
mailing list