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

V

Vinayakan Kuruvath

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.
 
Ö

Öö Tiib

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.

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.
 
V

Vinayakan Kuruvath

Thanks Tiib, I suspected it is something to do with making parsing easy. You have explained it so well.
 
B

Ben Bacarisse

Öö Tiib said:
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.

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);
{
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.

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.
 
Ö

Öö Tiib

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);

True. Thanks for correcting!
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.

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'.
 
B

Ben Bacarisse

Öö Tiib said:
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'.

Yes. And the '(' after 'if', 'while', 'switch' and 'for' are there for
symmetry alone. Ditto the ')' after the type name in a compound literal.
 
E

Eric Sosman

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.

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.
 
S

Scott Fluhrer

Ben Bacarisse said:
Yes. And the '(' after 'if', 'while', 'switch' and 'for' are there for
symmetry alone.

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.
 
G

guinness.tony

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

This is unambiguous in C-as-it-stands,

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);
 
E

Eric Sosman

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);

Oops! Right you are.
 
B

Ben Bacarisse

Eric Sosman said:
do while(A) while(B) while(C) while(D);

This is unambiguous in C-as-it-stands,

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).
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'.

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 ';'.
 
B

Ben Bacarisse

Scott Fluhrer said:
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 ;

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>
 
S

Scott Fluhrer

Ben Bacarisse said:
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.

Oops, sorry about that. You are correct.
 
B

BartC

do {
i++;
printf("Before continue --> i: %d\n", i);
if ( i == 7) continue;
printf("After continue --> i: %d\n", i);
} while (i < 10);
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.

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

That's a simple way of explaining it.
 
J

John Gordon

You don't need a semicolon following a closing brace such as }.
That's a simple way of explaining it.

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

struct foo
{
int i;
char c;
float f;
};
 
B

Ben Bacarisse

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

struct foo
{
int i;
char c;
float f;
};

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.
 
G

glen herrmannsfeldt

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.

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
 
B

BartC

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.

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.
 
B

Ben Bacarisse

BartC said:
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.

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.
 

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

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top