Block statements do not need to have semicolons after them, which is why we don't need a semicolon after the close brace in this code:

while (true) {
cout << "Hi!" << endl;
}

Any expression acting as a statement must have a semicolon after it, which is why the cout line above is terminated with a semicolon.

Control statements (if, do, while, switch, etc.) do not need a semicolon after them, except for do ... while, must have a semicolon after it. However, if the statement that they control ends with a semicolon, the overall statement itself will. For example:

while (true) cout << "Are we there yet?" << endl;

ends with a semicolon, because the controlled cout statement ends with a semicolon.

Control-flow changing statements like break, continue, goto, return, and throw must have semicolons after them.

Declaration statements like function prototypes, variable declarations, and struct/class/union declarations must be terminated with semicolons.

For a complete list of statement types and their syntax, you can check out §6 of the C++ ISO standard, which goes over the grammars for each of these types of statements. This is how I was able to compile this list.

(1) Macro definitions aren't statements. (2) main is not a keyword. (3) these identifiers (typenames) appear in many contexts, including inside statements. There is no relation between these typenames appearing in statements and the need for semicolons. (4) Function definitions aren't statements either.
–
MSaltersJun 15 '12 at 7:30