Why does a 'do .. while' loop need a semicolon terminator.

Discussion in 'C Programming' started by Vinayakan Kuruvath, Sep 24, 2013.

  1. Hi,

    #include <stdio.h>

    int main() {
    int i=0;
    do {
    i++;
    printf("Before continue --> i: %d\n", i);
    if ( i == 7) continue;
    printf("After continue --> i: %d\n", i);
    } while (i < 10);

    printf("Over\n");
    }


    In the above code, if I remove the semi-colon after the 'while (i< 10)' the parser will complain.

    I am just curious as to why a 'do ... while' loop syntax needs a semicolon at the end.

    Whereas for and while loop do not need a semi-colon terminator at end.

    Regards,
    Vinayakan.
     
    Vinayakan Kuruvath, Sep 24, 2013
    #1
    1. Advertisements

  2. Vinayakan Kuruvath

    Öö Tiib Guest

    The 'for' and 'while' loops need statement at the end. The compound
    statement does not need semicolon at end, but single statement or
    empty statement need semicolon at end:

    for (i=0; i<10; ++i) printf("Such i: %d\n", i); // <-- see?

    It would be ambiguous to parse 'while' loop inside 'do-while' loop
    if there was no semicolon required at end of 'do-while' loop.
    Like that:

    int a = 10;
    int b = 10;

    do
    while(a > 0) // does do-while end here? No. There are no semicolon.
    {
    printf("Such a: %d\n", a);
    a--;
    }
    while(a = b--);

    Other option could be to require always compound statement inside
    'do-while' loop. The authors of C did choose to require semicolon
    at end.
     
    Öö Tiib, Sep 24, 2013
    #2
    1. Advertisements

  3. Thanks Tiib, I suspected it is something to do with making parsing easy. You have explained it so well.
     
    Vinayakan Kuruvath, Sep 24, 2013
    #3
  4. There's no ambiguity here. 'do' must be followed by a statement, so the
    'while' is clearly the start of a statement, not the end of a
    'do...while'. The shortest 'do...while' has an empty statement in the
    middle:

    do ; while (C);
    I don't think there would be any ambiguity if the ';' at the end of
    'do...while' where not there. I think it's needed for symmetry rather
    than for parsing.
     
    Ben Bacarisse, Sep 24, 2013
    #4
  5. Vinayakan Kuruvath

    Öö Tiib Guest

    True. Thanks for correcting!
    Apparently. If to think of it then there is no parsing aid from
    semicolon after several other statements as well like 'break', 'continue'
    or 'goto somewhere'.
     
    Öö Tiib, Sep 24, 2013
    #5
  6. Yes. And the '(' after 'if', 'while', 'switch' and 'for' are there for
    symmetry alone. Ditto the ')' after the type name in a compound literal.
     
    Ben Bacarisse, Sep 24, 2013
    #6
  7. Vinayakan Kuruvath

    Eric Sosman Guest

    do while(A) while(B) while(C) while(D);

    This is unambiguous in C-as-it-stands, but if the trailing
    semicolon after `do-while' were omitted there would need to be
    some other rule to decide whether a `while' begins a statement
    nested within the `do-while' or whether it ends the `do-while'.
    Such a rule could certainly be invented, something like the rule
    for associating an `else' with the proper `if'. But I don't
    think simply dropping the semicolon would work without some
    other compensating change to the language.
     
    Eric Sosman, Sep 24, 2013
    #7
  8. Well, no, if you don't insist on the parens in an 'if'statement, then a
    string of tokens such as:

    if a * b == c - d ;

    becomes ambiguous; yes, you could come up with rules to disambiguate,
    however (in the above example) if the rules don't depend on the types of
    'a', 'b', 'c' and 'd', they'll quite likely not to match what the author
    meant.
     
    Scott Fluhrer, Sep 24, 2013
    #8
  9. This is uncompileable as it stands.

    You need a statement after while(C) and before while(D).
    An empty one will do:

    do while(A) while(B) while(C) ; while(D);
     
    guinness.tony, Sep 24, 2013
    #9
  10. Vinayakan Kuruvath

    Eric Sosman Guest

    Oops! Right you are.
     
    Eric Sosman, Sep 24, 2013
    #10
  11. Hmm, it's a syntax error, is it not? (I'm not contradicting you, a
    syntax error is as unambiguous as anything else, but I am not 100% sure
    what you gain from the example).
    I don't follow. In a construct like the above, each while must be the
    start of a new statement (the first inside the do and the rest inside
    the previous while. The semicolon ends the chain, so the parser now
    expects a 'while' to end the 'do'. When it seems it, it need not care
    if there is a ';' after the ')' or not. I.e the valid form of the above:

    do while(A) while(C) while(C) while(D); while(E);

    is as unambiguous (to my casual review of the syntax) with or without
    the trailing ';'.
     
    Ben Bacarisse, Sep 24, 2013
    #11
  12. I said nothing about omitting the ')'. The '(' is there for symmetry.
    Because we had been talking about symmetry, I mentioned a couple of
    other cases.

    <snip>
     
    Ben Bacarisse, Sep 24, 2013
    #12
  13. Oops, sorry about that. You are correct.
     
    Scott Fluhrer, Sep 24, 2013
    #13
  14. Vinayakan Kuruvath

    BartC Guest

    You don't need a semicolon following a closing brace such as }.

    That's a simple way of explaining it.
     
    BartC, Sep 24, 2013
    #14
  15. Vinayakan Kuruvath

    John Gordon Guest

    A semicolon following a closing brace is required in some contexts, such
    as declaring a struct.

    struct foo
    {
    int i;
    char c;
    float f;
    };
     
    John Gordon, Sep 24, 2013
    #15
  16. Also following a initialiser list, and after a compound literal in some
    situations:

    int a[] = {1, 2, 3};
    return (struct foo){1, 2};

    However, I'm sure that none of these relate to what BartC meant (rather
    than what he said). I'm sure the '}' referred to is the one that closes
    a compound statement, but, even so, I don't see how it answers the OP's
    question, simply or otherwise.
     
    Ben Bacarisse, Sep 24, 2013
    #16
  17. There are languages like Pascal, and I believe Algol, where the
    semicolon is a statement separator. In PL/I and C, it is a statement
    terminator. (Look at a description of Pascal to see the difference.)

    In PL/I, grouping of statements is done with DO; and END;

    IF A=B THEN DO;
    PUT SKIP LIST(A);
    PUT SKIP LIST(B);
    END;

    (I learned PL/I before C.)

    Following that, the C { replaces DO; and } replaces END;

    You will find sometimes people use do ... while(0) in macros
    to avoid the semicolon confusion that otherwise results.

    -- glen
     
    glen herrmannsfeldt, Sep 24, 2013
    #17
  18. Vinayakan Kuruvath

    BartC Guest

    The OP was presumably thinking about other loops such as these:

    for (a; b; c) {d; e;}
    while (a) {b; c;}

    which all finish with a compound statement and hence no semicolon ends the
    loop, and comparing to this:

    do {a; b;} while (c);

    which also has a compound statement as a body, that doesn't need a
    semicolon, but it's not the end of the loop.

    So the first two examples end with }, the last with ). According to my
    simple rule, the first two don't need a semicolon.
     
    BartC, Sep 24, 2013
    #18
  19. The OP asked "why the do while needs a semicolon" and that, to me, needs
    a deeper answer than giving a rule which re-states a consequence of the
    syntax (the key words being "why" and "needs"). Since I don't think
    it's needed at all, any explanation of why it's needed, is going to look
    wrong to me.
     
    Ben Bacarisse, Sep 24, 2013
    #19
  20. best explanation.
     
    Nitin Tripathi, Sep 25, 2013
    #20
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.