469,613 Members | 1,204 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,613 developers. It's quick & easy.

Static checking of C programs with LCLint

8 5082
aa*****@gmail.com said:
Hi all,
see:-
http://linuxgazette.net/issue51/pramode.html
From that page: "Here is a small C program:

main()
{
int a[10];
if (sizeof(a)/sizeof(a[0]) -1)
printf("hello\n");
}

We expected this to print hello, but it did not."

You might have expected that, but I didn't. I expected it to exhibit
undefined behaviour.

"gcc did not give us any hint."

Really?

foo.c:2: warning: return-type defaults to `int'
foo.c:2: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:4: warning: comparison between signed and unsigned
foo.c:5: warning: implicit declaration of function `printf'
foo.c:6: warning: control reaches end of non-void function

That looks like quite a few hints to me.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #2
On Apr 14, 8:04*am, Richard Heathfield <r...@see.sig.invalidwrote:
aark...@gmail.com said:
Hi all,
see:-
http://linuxgazette.net/issue51/pramode.html

From that page: "Here is a small C program:

main()
{
* * * * int a[10];
* * * * if (sizeof(a)/sizeof(a[0]) -1)
* * * * * * printf("hello\n");

}

*We expected this to print hello, but it did not."

You might have expected that, but I didn't. I expected it to exhibit
undefined behaviour.

"gcc did not give us any hint."

Really?

foo.c:2: warning: return-type defaults to `int'
foo.c:2: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:4: warning: comparison between signed and unsigned
foo.c:5: warning: implicit declaration of function `printf'
foo.c:6: warning: control reaches end of non-void function

That looks like quite a few hints to me.
Then again, the article is 7 years old and it was even before the name
change from LCLint to SPLint.
I guess it would have been GCC 2.95 or so back then.
Jun 27 '08 #3
user923005 said:
On Apr 14, 8:04 am, Richard Heathfield <r...@see.sig.invalidwrote:
>aark...@gmail.com said:
Hi all,
see:-
http://linuxgazette.net/issue51/pramode.html

From that page: "Here is a small C program:

main()
{
int a[10];
if (sizeof(a)/sizeof(a[0]) -1)
printf("hello\n");

}

We expected this to print hello, but it did not."

You might have expected that, but I didn't. I expected it to exhibit
undefined behaviour.

"gcc did not give us any hint."

Really?

foo.c:2: warning: return-type defaults to `int'
foo.c:2: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:4: warning: comparison between signed and unsigned
foo.c:5: warning: implicit declaration of function `printf'
foo.c:6: warning: control reaches end of non-void function

That looks like quite a few hints to me.

Then again, the article is 7 years old and it was even before the name
change from LCLint to SPLint.
I guess it would have been GCC 2.95 or so back then.
The above diagnostics were produced by gcc 2.95.3

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #4
On Apr 14, 12:18*pm, Richard Heathfield <r...@see.sig.invalidwrote:
user923005 said:


On Apr 14, 8:04 am, Richard Heathfield <r...@see.sig.invalidwrote:
aark...@gmail.com said:
Hi all,
see:-
http://linuxgazette.net/issue51/pramode.html
From that page: "Here is a small C program:
main()
{
int a[10];
if (sizeof(a)/sizeof(a[0]) -1)
printf("hello\n");
}
We expected this to print hello, but it did not."
You might have expected that, but I didn't. I expected it to exhibit
undefined behaviour.
"gcc did not give us any hint."
Really?
foo.c:2: warning: return-type defaults to `int'
foo.c:2: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:4: warning: comparison between signed and unsigned
foo.c:5: warning: implicit declaration of function `printf'
foo.c:6: warning: control reaches end of non-void function
That looks like quite a few hints to me.
Then again, the article is 7 years old and it was even before the name
change from LCLint to SPLint.
I guess it would have been GCC 2.95 or so back then.

The above diagnostics were produced by gcc 2.95.3
Here is the code from the article {reformatted a bit}, along with
compiler and lint diagnostics:

#include <stdlib.h>
#include <stdio.h>

int main00()
{
int a[10];
if (sizeof(a) / sizeof(a[0]) -1)
printf("hello\n");
}
int main01()
{
int a = 0;
while (a = 1)
printf("hello\n");
return 0;
}

int main02()
{
int *p = malloc(5 * sizeof(int));
*p = 1;
free(p);
return 0;
}

int main03()
{
int *p = malloc(5 * sizeof(int));
if (p == NULL) {
fprintf(stderr, "error in malloc");
exit(EXIT_FAILURE);
} else
*p = 1;
free(p);
return 0;
}
int main04()
{
int *p = malloc(5 * sizeof(int));
int *q;
q = p;
free(q);
free(p);
return 0;
}

#define sqr(p) p * p
int main05()
{
int i = 2,
j;
j = sqr(i + 1);
printf("%d", j); /* prints 5 */
return 0;
}
static void foo0(int *a, int *b)
{ /* @modifies *a@ */
*a = 1, *b = 2;
}
int main06()
{
int p = 10,
q = 20;
foo0(&p, &q);
return 0;
}
static void foo1(int *a, int *b)
{ /* @modifies nothing@ */
*a = 1, *b = 2;
}
int main07()
{
int p = 10,
q = 20;
foo1(&p, &q);
return 0;
}

static int abc,
def;
static void foo2()
{

def = 1;
}
int main08()
{
int p = 10,
q = 20;
foo2(&p, &q);
return 0;
}

int main(void)
{
int i;
i = main00();
i = main01();
i = main02();
i = main03();
i = main04();
i = main05();
i = main06();
i = main07();
i = main08();
return 0;
}
/*
$ gcc -W -Wall -ansi -pedantic foo.c
foo.c: In function `main00':
foo.c:7: warning: comparison between signed and unsigned
foo.c:9: warning: control reaches end of non-void function
foo.c: In function `main01':
foo.c:15: warning: suggest parentheses around assignment used as truth
value
foo.c: At top level:
foo.c:93: warning: `abc' defined but not used

C:\tmp>cl /W4 /Ox foo.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762
for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

foo.c
foo.c(7) : warning C4308: negative integral constant converted to
unsigned type
foo.c(7) : warning C4127: conditional expression is constant
c:\tmp\foo.c(9) : warning C4716: 'main00' : must return a value
c:\tmp\foo.c(15) : warning C4706: assignment within conditional
expression
c:\tmp\foo.c(112) : warning C4702: unreachable code
c:\tmp\foo.c(117) : warning C4702: unreachable code
c:\tmp\foo.c(118) : warning C4702: unreachable code
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.

splint:
foo.c: (in function main00)
foo.c(7,15): Operands of have incompatible types (arbitrary unsigned
integral
type, int): sizeof((a)) / sizeof((a[0])) -1
To allow arbitrary integral types to match any integral type, use
+matchanyintegral.
foo.c(9,2): Path with no return in function declared to return int
There is a path through a function declared to return a value on
which there
is no return statement. This means the execution may fall through
without
returning a meaningful result to the caller. (Use -noret to inhibit
warning)
foo.c: (in function main01)
foo.c(15,12): Test expression for while is assignment expression: a =
1
The condition test is an assignment expression. Probably, you mean
to use ==
instead of =. If an assignment is intended, add an extra parentheses
nesting
(e.g., if ((a = b)) ...) to suppress this message. (Use -predassign
to
inhibit warning)
foo.c(15,12): Test expression for while not boolean, type int: a = 1
Test expression type is not boolean or int. (Use -predboolint to
inhibit
warning)
foo.c: (in function main02)
foo.c(23,6): Dereference of possibly null pointer p: *p
A possibly null pointer is dereferenced. Value is either the result
of a
function which may return null (in which case, code should check it
is not
null), or a global, parameter or structure field declared with the
null
qualifier. (Use -nullderef to inhibit warning)
foo.c(22,25): Storage p may become null
foo.c: (in function main04)
foo.c(49,10): Dead storage p passed as out parameter to free: p
Memory is used after it has been released (either by passing as an
only param
or assigning to an only global). (Use -usereleased to inhibit
warning)
foo.c(48,10): Storage p released
foo.c(93,17): File static variable abc declared but not used
A variable is declared but never used. Use /*@unused@*/ in front of
declaration to suppress message. (Use -varuse to inhibit warning)
foo.c(4,17): Function exported but not used outside foo: main00
A declaration is exported, but not used outside this module.
Declaration can
use static qualifier. (Use -exportlocal to inhibit warning)
foo.c(9,1): Definition of main00
foo.c(12,17): Function exported but not used outside foo: main01
foo.c(18,1): Definition of main01
foo.c(20,17): Function exported but not used outside foo: main02
foo.c(26,1): Definition of main02
foo.c(30,17): Function exported but not used outside foo: main03
foo.c(40,1): Definition of main03
foo.c(43,17): Function exported but not used outside foo: main04
foo.c(51,1): Definition of main04
foo.c(56,17): Function exported but not used outside foo: main05
foo.c(63,1): Definition of main05
foo.c(70,17): Function exported but not used outside foo: main06
foo.c(76,1): Definition of main06
foo.c(83,17): Function exported but not used outside foo: main07
foo.c(89,1): Definition of main07
foo.c(100,17): Function exported but not used outside foo: main08
foo.c(106,1): Definition of main08

PC-Lint:

--- Module: foo.c (C)
_
if (sizeof(a) / sizeof(a[0]) -1)
foo.c(7) : Warning 574: Signed-unsigned mix with relational
foo.c(7) : Info 737: Loss of sign in promotion from int to unsigned
int
foo.c(7) : Warning 506: Constant value Boolean
foo.c(7) : Info 774: Boolean within 'if' always evaluates to False
[Reference:
file foo.c: line 7]
foo.c(7) : Info 831: Reference cited in prior message
_
}
foo.c(9) : Warning 533: function 'main00(void)' should return a value
(see line
4)
foo.c(4) : Info 830: Location cited in prior message
_
}
foo.c(9) : Warning 550: Symbol 'a' (line 6) not accessed
foo.c(6) : Info 830: Location cited in prior message
_
}
foo.c(9) : Note 953: Variable 'a' (line 6) could be declared as const
--- Eff.
C++ 3rd Ed. item 3
foo.c(6) : Info 830: Location cited in prior message
_
while (a = 1)
foo.c(15) : Info 720: Boolean test of assignment
foo.c(15) : Warning 506: Constant value Boolean
_
return 0;
foo.c(17) : Warning 527: Unreachable code at token 'return'
_
}
foo.c(18) : Warning 550: Symbol 'a' (line 14) not accessed
foo.c(14) : Info 830: Location cited in prior message
_
*p = 1;
foo.c(23) : Warning 613: Possible use of null pointer 'p' in argument
to
operator 'unary *' [Reference: file foo.c: line 22]
foo.c(22) : Info 831: Reference cited in prior message
_
#define sqr(p) p * p
foo.c(55) : Info 773: Expression-like macro 'sqr' not parenthesized
_
j = sqr(i + 1);
foo.c(60) : Warning 665: Unparenthesized parameter 1 in macro 'sqr' is
passed
an expression
foo.c(60) : Warning 665: Unparenthesized parameter 1 in macro 'sqr' is
passed
an expression
_
}
foo.c(63) : Note 953: Variable 'i' (line 58) could be declared as
const ---
Eff. C++ 3rd Ed. item 3
foo.c(58) : Info 830: Location cited in prior message
_
foo2(&p, &q);
foo.c(104) : Error 119: Too many arguments (2) for prototype
'foo2(void)'
_
}
foo.c(121) : Warning 550: Symbol 'i' (line 110) not accessed
foo.c(110) : Info 830: Location cited in prior message

--- Wrap-up for Module: foo.c

Warning 528: Symbol 'abc' (line 93, file foo.c) not referenced
foo.c(93) : Info 830: Location cited in prior message
Warning 551: Symbol 'def' (line 94, file foo.c) not accessed
foo.c(94) : Info 830: Location cited in prior message

*/
Jun 27 '08 #5
On Mon, 14 Apr 2008 15:04:15 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote:
aa*****@gmail.com said:
http://linuxgazette.net/issue51/pramode.html

From that page: "Here is a small C program:

main()
{
int a[10];
if (sizeof(a)/sizeof(a[0]) -1)
printf("hello\n");
}

We expected this to print hello, but it did not."

You might have expected that, but I didn't. I expected it to exhibit
undefined behaviour.
I didn't, unless size_t is narrower than signed int (which is
permitted, but rarely sensical). Otherwise, the printf call is never
executed, and has no opportunity to cause UB.

In C<99 it does produce unspecified exit status, which is bad, but not
UB. The other style points are also bad style but not UB.

- formerly david.thompson1 || achar(64) || worldnet.att.net
Jun 27 '08 #6
David Thompson wrote:
Richard Heathfield <rj*@see.sig.invalidwrote:
.... snip ...
>
>From that page: "Here is a small C program:

main() {
int a[10];
if (sizeof(a)/sizeof(a[0]) -1)
printf("hello\n");
}

We expected this to print hello, but it did not."

You might have expected that, but I didn't. I expected it to
exhibit undefined behaviour.

I didn't, unless size_t is narrower than signed int (which is
permitted, but rarely sensical). Otherwise, the printf call is
never executed, and has no opportunity to cause UB.
I didn't, since the quotient of two unsigned values is unsigned,
and the unsigned equivalent of -1 is always the maximum unsigned
value, and thus the conditional is never true.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

** Posted from http://www.teranews.com **
Jun 27 '08 #7
CBFalconer wrote:
[...] the quotient of two unsigned values is unsigned, [...]
Not if the unsigned values ("types," really) promote
to int, which is signed. That would be unusual for size_t
values, as David Thompson pointed out, but is quite common
with unsigned short, unsigned char, and unsigned bit-fields.

--
Er*********@sun.com
Jun 27 '08 #8
Eric Sosman wrote:
CBFalconer wrote:
>[...] the quotient of two unsigned values is unsigned, [...]

Not if the unsigned values ("types," really) promote
to int, which is signed. That would be unusual for size_t
values, as David Thompson pointed out, but is quite common
with unsigned short, unsigned char, and unsigned bit-fields.
True. A useful exception to keep in mind.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

12 posts views Thread by Michael Muller | last post: by
467 posts views Thread by mike420 | last post: by
49 posts views Thread by bearophileHUGS | last post: by
1 post views Thread by Christoph W. Lueken | last post: by
8 posts views Thread by Peter B. Steiger | last post: by
3 posts views Thread by Zhigang Cui | last post: by
74 posts views Thread by Mark | last post: by
18 posts views Thread by Ronald Bruck | last post: by
125 posts views Thread by jacob navia | last post: by
reply views Thread by devrayhaan | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.