Static checking of C programs with LCLint
Collapse
This topic is closed.
X
X
-
aarklon@gmail.comTags: None -
Richard Heathfield
Re: Static checking of C programs with LCLint
aarklon@gmail.c om said:
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
-
user923005
Re: Static checking of C programs with LCLint
On Apr 14, 8:04 am, Richard Heathfield <r...@see.sig.i nvalidwrote:Then again, the article is 7 years old and it was even before the nameaark...@gmail.c om said:
>>>Hi all,
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.
change from LCLint to SPLint.
I guess it would have been GCC 2.95 or so back then.
Comment
-
Richard Heathfield
Re: Static checking of C programs with LCLint
user923005 said:
The above diagnostics were produced by gcc 2.95.3On Apr 14, 8:04 am, Richard Heathfield <r...@see.sig.i nvalidwrote:>>aark...@gmail. com said:
>>>>>>Hi all,
>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.
--
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
Comment
-
user923005
Re: Static checking of C programs with LCLint
On Apr 14, 12:18 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:Here is the code from the article {reformatted a bit}, along withuser923005 said:
>
>
>
>
>>On Apr 14, 8:04 am, Richard Heathfield <r...@see.sig.i nvalidwrote:aark...@gmail.c om said:>>Hi all,>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
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_FAILU RE);
} 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(11 2) : warning C4702: unreachable code
c:\tmp\foo.c(11 7) : warning C4702: unreachable code
c:\tmp\foo.c(11 8) : 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
+matchanyintegr al.
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
*/
Comment
-
David Thompson
Re: Static checking of C programs with LCLint
On Mon, 14 Apr 2008 15:04:15 +0000, Richard Heathfield
<rjh@see.sig.in validwrote:
aarklon@gmail.c om said:I didn't, unless size_t is narrower than signed int (which is>
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.
>
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.ne t
Comment
-
CBFalconer
Re: Static checking of C programs with LCLint
David Thompson wrote:.... snip ...Richard Heathfield <rjh@see.sig.in validwrote:
>I didn't, since the quotient of two unsigned values is unsigned,>>>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.
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 **
Comment
-
Eric Sosman
Re: Static checking of C programs with LCLint
CBFalconer wrote:Not if the unsigned values ("types," really) promote[...] the quotient of two unsigned values is unsigned, [...]
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.
--
Eric.Sosman@sun .com
Comment
-
CBFalconer
Re: Static checking of C programs with LCLint
Eric Sosman wrote:True. A useful exception to keep in mind.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.
--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.
** Posted from http://www.teranews.com **
Comment
Comment