views:

731

answers:

9
int main()
{
  int var = 0;; // Typo which compiles just fine
}
+11  A: 

Because you might need something like this:

while (x++ < 10);

In this statement, the semicolon is considered the while body. It's still a valid statement but it doesn't do anything. This increases the consistency of the language.

Mehrdad Afshari
I think your example is an argument in favour of making it illegal (an empty block here instead would be more legible). But your point about consistency remains valid.
Konrad Rudolph
Why not just do x = 11?
Unknown
@Unknown because the condition is not always so simple. Sometimes like advancing an iterator, or w/e (yes, I know that there is std::advance)
Edison Gustavo Muenz
This is a good example of how C can be very concise, but this breaks at least 2 MISRA-C rules. Suggest: while (x < 10) {x++;}
Steve Melnikoff
+8  A: 

I'm no language designer, but the answer I'd give is "why not?" From the language design perspective, one wants the rules (i.e. the grammar) to be as simple as possible.

Not to mention that "empty expressions" have uses, i.e.

for (i = 0; i < INSANE_NUMBER; i++);

Will dead-wait (not a good use, but a use nonetheless).

EDIT: As pointed out in a comment to this answer, any compiler worth its salt would probably not busy wait at this loop, and optimize it away. However, if there were something more useful in the for head itself (other than i++), which I've seen done (strangely) with data structure traversal, then I imagine you could still construct a loop with an empty body (by using/abusing the "for" construct).

Dan Fego
Will that actually wait? Can the compiler optimize away the loop since nothing happens?
Tom
Good question. Now that you mention it, I don't know. All I know is that it *should*. :)
Dan Fego
@Tom: Good question. In C++ at least, according to the standard, execution time is not explicitly part of the "observable behaviour" of the system, so in theory I suppose a compiler could optimise this out. However, if i is volatile then this optimisation is forbidden.
j_random_hacker
+3  A: 

The most common case is probably

int i = 0;
for (/* empty*/; i != 10; ++i) {
    if (x[i].bad) break;
}
if (i != 10) {
    /* panic */
}
MSalters
+1  A: 
while(1){
    ; /* do nothing */
}

There are times when you want to sit and do nothing. An event/interrupt driven embedded application or when you don't want a function to exit such as when setting up threads and waiting for the first context switch.

example: http://lxr.linux.no/linux+v2.6.29/arch/m68k/mac/misc.c#L523

Sweeney
CPU cooling test?
lc
You don't need the semicolon there!
Thomas Padron-McCarthy
used usually in benchmark shootouts between languages :)
gbjbaanb
You could write while(1); And true, in some cases you do not need the ';' however that is not true with all compilers. A fair amount of embedded compilers will yell at you if you are missing it. However you are correct that in the ANSI C Grammar it is not required.
Sweeney
+12  A: 

It's obviously so we can say things like

for(;;) {
  // stuff
}

Who could live without that?

anon
God forbid we use goto!
Marc Bernier
That's not a good example, because, for example, the second semicolon is not used to end a statement. The second clause of the for is an expression; and leaving that empty is treated as a special case making it equivalent to true.
newacct
The original question was about expressions, not statements.
anon
+4  A: 

I honestly don't know if this is the real reason, but I think something that makes more sense is to think about it from the standpoint of a compiler implementer.

Large portions of compilers are built by automated tools that analyze special classes of grammars. It seems very natural that useful grammars would allow for empty statements. It seems like unnecessary work to detect such an "error" when it doesn't change the semantics of your code. The empty statement won't do anything, as the compiler won't generate code for those statements.

It seems to me that this is just a result of "Don't fix something that isn't broken"...

Tom
DMR's original C compiler (which is where this syntax comes from) was a recursive descent compiler - such compilers are normally hand written, so I don't think the toolds were an issue here.
anon
That almost makes it seem *more likely* that this sort of thing would happen. If you are handcoding a r.d.p., then you are writing a function for every production in your grammar whose job is to match the next stretch of input... If expressions and other stuff make up statements, and both expressions and other stuff can end up consuming no input (except for the ultimate semicolon to follow), then the parser would recognize such statements. Idk if this is the real reason, but it seems like a reasonable way to reason it out. (I never wrote a huge r.d.p., but I have written one before).
Tom
I am looking now at one particular Yacc grammar for a C-like language, and the empty statement requires an extra rule, so the opposite seems to be true. At least with that grammar, for that language, for that tool.
Thomas Padron-McCarthy
+13  A: 

How else could assert(foo == bar); compile down to nothing when NDEBUG is defined?

j_random_hacker
+8  A: 

This is the way C and C++ express NOP.

mouviciel
Which is of prime importance on tight-budget microcontroller systems.
jpinto3912
@jpinto3912: In fact `;` will almost certainly compile down to *no instructions at all*, rather than to the target platform's `NOP` instruction.
j_random_hacker
+2  A: 

You want to be able to do things like

while ( fnorble(the_smurf) == FAILED )
    ;

and not

while ( fnorble(the_smurf) == FAILED )
    do_nothing_just_because_you_have_to_write_something_here();

But! Please do not write the empty statement on the same line, like this:

while ( fnorble(the_smurf) == FAILED );

That's a very good way to confuse the reader, since it is easy to miss the semicolon, and therefore think that the next row is the body of the loop. Remember: Programming is really about communication -- not with the compiler, but with other people, who will read your code. (Or with yourself, three years later!)

Thomas Padron-McCarthy