|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
|
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
aarklon@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 |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Apr 14, 8:04am, Richard Heathfield <r...@see.sig.invalid> wrote:
> 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. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
user923005 said:
> On Apr 14, 8:04 am, Richard Heathfield <r...@see.sig.invalid> wrote: >> 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 |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Apr 14, 12:18pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> user923005 said: > > > > > > > On Apr 14, 8:04 am, Richard Heathfield <r...@see.sig.invalid> wrote: > >> 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 */ |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Mon, 14 Apr 2008 15:04:15 +0000, Richard Heathfield
<rjh@see.sig.invalid> wrote: > aarklon@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 |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
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. -- Eric.Sosman@sun.com |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
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 ** |
|
![]() |
| Outils de la discussion | |
|
|