Is this wrong or is splint broken?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Army1987

    Is this wrong or is splint broken?

    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(car d, &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_FAILU RE);
    }
    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...
    --
    Army1987 (Replace "NOSPAM" with "email")
    "Never attribute to malice that which can be adequately explained
    by stupidity." -- R. J. Hanlon (?)

  • Doug

    #2
    Re: Is this wrong or is splint broken?


    Army1987 wrote:
    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

    Comment

    • Old Wolf

      #3
      Re: Is this wrong or is splint broken?

      On Aug 8, 2:53 am, Army1987 <army1...@NOSPA M.itwrote:
      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;

      Comment

      • Army1987

        #4
        Re: Is this wrong or is splint broken?

        On Tue, 07 Aug 2007 09:07:06 -0700, Doug wrote:
        >
        Army1987 wrote:
        >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@army19 87-laptop:~$ cat foo.c
        #include <stdio.h>
        #include <stdlib.h>
        extern int is_prime(unsign ed);
        int main(void)
        {
        unsigned k = 0;
        if (scanf("%u", &k) < 1) {
        fputs("Invalid\ n", stderr);
        exit(EXIT_FAILU RE);
        }
        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@army19 87-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@army19 87-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...)

        --
        Army1987 (Replace "NOSPAM" with "email")
        "Never attribute to malice that which can be adequately explained
        by stupidity." -- R. J. Hanlon (?)

        Comment

        Working...