Question: 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

```

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

```
Flow control statement consistency
----------------------------------

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

Consistency of statement delimiters
-----------------------------------

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:

* people sometimes make mistakes (or have them transiently as the code's massaged) and if it visually stands out that means it will be fixed more easily, and
* macro substitutions can throw together lots of statements on one line, and we occasionally need to visually verify the preprocessor output while troubleshooting or doing QA.

Implications to preprocessor use
--------------------------------

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.