My guess is it just made parsing easier, but I can't see exactly why.
So what does this have ...
do
{
some stuff
}
while(test);
more stuff
that's better than ...
do
{
some stuff
}
while(test)
more stuff
My guess is it just made parsing easier, but I can't see exactly why.
So what does this have ...
do
{
some stuff
}
while(test);
more stuff
that's better than ...
do
{
some stuff
}
while(test)
more stuff
Because you're ending the statement. A statement ends either with a block (delimited by curly braces), or with a semicolon. "do this while this" is a single statement, and can't end with a block (because it ends with the "while"), so it needs a semicolon just like any other statement.
If you take a look at C++ grammar, you'll see that the iteration statements are defined as
while ( condition ) statement
for ( for-init-statement condition-opt ; expression-opt ) statement
do statement while ( expression ) ;
Note that only do-while
statement has an ;
at the end. So, the question is why the do-while
is so different from the rest that it needs that extra ;
.
Let's take a closer look: both for
and regular while
end with a statement. But do-while
ends with a controlling expression enclosed in ()
. The presence of that enclosing ()
already allows the compiler to unambiguously find the end of the controlling expression: the outer closing )
designates where the expression ends and, therefore, where the entire do-while
statement ends. In other words, the terminating ;
is indeed redundant.
However, in practice that would mean that, for example, the following code
do
{
/* whatever */
} while (i + 2) * j > 0;
while valid from the grammar point of view, would really be parsed as
do
{
/* whatever */
} while (i + 2)
*j > 0;
This is formally sound, but it is not really intuitive. I'd guess that for such reasons it was decided to add a more explicit terminator to the do-while
statement - a semicolon. Of course, per @Joe White's answer there are also considerations of plain and simple consistency: all ordinary (non-compound) statements in C end with a ;
.
It's because while statements are valid within a do-while loop.
Consider the different behaviors if the semicolon weren't required:
int x = 10;
int y = 10;
do
while(x > 0)
x--;
while(x = y--);
While I don't know the answer, consistency seems like the best argument. Every statement group in C/C++ is either terminated by
Why create a construct which does neither?
Considering consistency...
if (expr) statement;
do statement; while (expr);
for (expr; expr; expr) statement;
while (expr) statement;
...all these flow-control constructs, end with a semicolon.
But, countering that we can note that of the block-statement forms, only do while
is semicolon delimited:
if (expr) { ... }
do { ... } while (expr);
for (expr; expr; expr) { }
while (expr) { }
So, we have ';' or '}', but never a "bare" ')'.
We can at least say that every statement must be delimited by ;
or }
, and visually that helps us distinguish statements.
If no semicolon were required, consider:
do statement1; while (expr1) statement2; do ; while (expr2) statement3; while (expr3) statement4;
It's very difficult to visually resolve that to the distinct statements:
do statement1; while (expr1)
statement2;
do ; while (expr2)
statement3;
while (expr3) statement4;
By way of contrast, the following is more easily resolved as a ;
immediately after a while
condition tells you to seek backwards for the do
, and that the next statement is unconnected to that while
:
do statement1; while (expr1); statement2; do ; while (expr2); statement3; while (expr3) statement4;
Does it matter, given people indent their code to make the flow understandable? Yes, because:
It's also worth noting the famous preprocessor do-while idiom:
#define F(X) do { fn(X); } while (false)
This can be substituted as follows:
if (expr)
F(x);
else
x = 10;
...yields...
if (expr)
do ( fn(x); } while (false);
else
x = 10;
If the semicolon wasn't part of the do while
statement, then the if
statement would be interpreted as:
if (expr)
do-while-statement
; // empty statement
else
x = 10;
...and, because there are two statements after the if
, it's considered complete, which leaves the else
statement unmatched.
C is semicolon-terminated (whereas Pascal is semicolon-separated). It would be inconsistent to drop the semicolon there.
I, frankly, hate the reuse of the while for the do loop. I think repeat-until would have been less confusing. But it is what it is.
My answer is that, the compiler may get confusion, when we didn't include the semicolon in the termination of do.....while();
loop. Without this it is not clear about:
That's why we include semicolon in the end of do......while
loop, to indicate the loop is terminating here if the condition is false.
In C/C++ whitespace don't contribute to structure (like e.g. in python). In C/C++ statements must be terminated with a semicolon. This is allowed:
do
{
some stuff; more stuff; even more stuff;
}
while(test);