Is this wrong or is splint broken?

A

Army1987

I can see no problem [1] with the loop below, and gcc compiles it
without complaining no matter how many warnings I enable, but
splint has a parse error on line 103 (marked below), column 22. Is
it seriously broken, or am I missing something?

while (!done) { /* line 76 */
switch (getans("Hit, Stand, suRrender, or Double down? ",
"hsrd")) {
case 'r':
credit -= wager / 2;
goto restart;
case 'd':
if (credit < 2 * wager) {
puts("You don't have enough money.");
break;
} else {
wager *= 2;
done = 1;
}
/* fall through */
case 'h':
card = drawcard(&deck);
printf("You got: %s of %s. ",
cardnames[card.rank], suitnames[card.suit]);
add_to_hand(card, &plhand);
printf("Your score is %u.\n", plhand.score);
if (plhand.bust) {
puts("You busted.");
/* fall through */
case 's':
done = 1;
}
break; /* line 103; column 22 is the semicolon. */
default:
fputs("End-of-file encountered or read error.\n", stderr);
exit(EXIT_FAILURE);
}
if (plhand.score == 21)
done = 1;
}

[1] I know that goto is evil, but I had to jump out of a switch
statement and two while statements at once, without jumping out of
the outermost of the three while statements...
 
D

Doug

Army1987 said:
I can see no problem [1] with the loop below, and gcc compiles it
without complaining no matter how many warnings I enable, but
splint has a parse error on line 103 (marked below), column 22. Is
it seriously broken, or am I missing something?

Hi there,

IMHO the code seems fine. You've got a case label within an if {}
block - I imagine this is why splint is whining. It's probably trying
to balance { and }, and wants to do so within basic blocks, and so it
probably gets confused because it thinks the case statement is the
start of another basic block.

Looks similar to Duff's device. Might be interesting to see what
splint says about that. I'd guess splint is broken in this respect.

Hope that helps, probably won't :)

Doug
 
O

Old Wolf

I can see no problem [1] with the loop below, and gcc compiles it
without complaining no matter how many warnings I enable, but
splint has a parse error on line 103 (marked below), column 22. Is
if (plhand.bust) {
puts("You busted.");
/* fall through */
case 's':
done = 1;
}
break; /* line 103; column 22 is the semicolon. */

Obv it doesn't like the case label within the
if block. Note that it is simple to restructure
the code to not use this hack, e.g.:

if ( plhand.bust )
{
puts("You busted");
done = 1;
}
break;

case s:
done = 1;

which I think is easier to read too.
If you really must share the cases (e.g. if there
is a lot of extra code you haven't shown), then:

if ( !plhand.bust )
break;

puts("You busted");
case 's':
done = 1;
 
A

Army1987

I can see no problem [1] with the loop below, and gcc compiles it
without complaining no matter how many warnings I enable, but
splint has a parse error on line 103 (marked below), column 22. Is
it seriously broken, or am I missing something?

Hi there,

IMHO the code seems fine. You've got a case label within an if {}
block - I imagine this is why splint is whining. It's probably trying
to balance { and }, and wants to do so within basic blocks, and so it
probably gets confused because it thinks the case statement is the
start of another basic block.
Yes, it is that which confuses it.
army1987@army1987-laptop:~$ cat foo.c
#include <stdio.h>
#include <stdlib.h>
extern int is_prime(unsigned);
int main(void)
{
unsigned k = 0;
if (scanf("%u", &k) < 1) {
fputs("Invalid\n", stderr);
exit(EXIT_FAILURE);
}
switch (k) {
case 0:
case 1:
puts("k is neither prime nor composite");
break;
default:
if (is_prime(k))
case 2:
case 3:
case 5:
puts("k is prime");
else
case 4:
case 6:
puts("k is composite");
}
return 0;
}
army1987@army1987-laptop:~$ splint foo.c
Splint 3.1.1 --- 20 Jun 2006

foo.c: (in function main)
foo.c:8:2: Return value (type int) ignored: fputs("Invalid\n...
Result returned by function call is not used. If this is intended, can cast
result to (void) to eliminate message. (Use -retvalint to inhibit warning)
foo.c:14:2: Return value (type int) ignored: puts("k is neith...
foo.c:17:6: Test expression for if not boolean, type int: is_prime(k)
Test expression type is not boolean or int. (Use -predboolint to inhibit
warning)
foo.c:19:9: Parse Error: Likely parse error. Conditional clauses are
inconsistent.. (For help on parse errors, see splint -help parseerrors.)
*** Cannot continue.
army1987@army1987-laptop:~$


(There are more serious bugs, for example, given:
unsigned wager;
/* ... */
printf("%g\n", wager / 2.0);
It complains that the second argument of printf has type unsigned
instead of double...)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top