int main()
{
int var = 0;; // Typo which compiles just fine
}
In both C and C++, this is allowed because an expression-statement may be just a ;
, which makes it a "null statement". Why is this allowed?
int main()
{
int var = 0;; // Typo which compiles just fine
}
In both C and C++, this is allowed because an expression-statement may be just a ;
, which makes it a "null statement". Why is this allowed?
How else could assert(foo == bar);
compile down to nothing when NDEBUG
is defined?
0
or ((void) 0)
would probably be fine too, but anyway...
Commented
Nov 14, 2011 at 20:04
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!)
continue
: while (fnorble(the_smurf) == FAILED) continue;
(preferably with the continue;
statement on its own line — here it is not possible due to the formatting constraints of Stack Overflow comments). Another option is do; while (fnorble(the_smurf) == FAILED);
, but I personally like it less.
This is the way C and C++ express NOP.
;
will almost certainly compile down to no instructions at all, rather than to the target platform's NOP
instruction.
Commented
Aug 14, 2010 at 4:00
;
certainly isn't it. You will need intrinsics or inline ASM for that. A stray ;
will just be optimized away to no instructions at all. This answer is incorrect.
Commented
Oct 8, 2023 at 18:32
OK, I’ll add this to the worst case scenario that you may actually use:
for (int yy = 0; yy < nHeight; ++yy) {
for (int xx = 0; xx < nWidth; ++xx) {
for (int vv = yy - 3; vv <= yy + 3; ++vv) {
for (int uu = xx - 3; uu <= xx + 3; ++uu) {
if (test(uu, vv)) {
goto Next;
}
}
}
Next:;
}
}
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).
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"...
Obviously, it is so that we can say things like
for (;;) {
// stuff
}
Who could live without that?
;
inside the header of for
have nothing in common with the ;
in the OP's question. What you have inside for
header are not statements at all. And the ;
in the above for
are not "empty statements". The ;
in for
are simply hardcoded characters of for
syntax with no special meaning. Only the first section of for
header is referred as "statement" in the language spec, but even that one is a special kind of for
-specific pseudo-statement with its own dedicated grammar.
Commented
Oct 24, 2013 at 23:13
for(;;)
is legal has absolutely nothing to do with the fact that empty statements are legal. The two are described by their own, absolutely unrelated parts of the grammar and language spec.
Commented
Oct 24, 2013 at 23:14
There are already many good answers but have not seen the productive-environment sample.
Here is FreeBSD's implementation of strlen
:
size_t
strlen(const char *str)
{
const char *s;
for (s = str; *s; ++s)
;
return (s - str);
}
When using ;
, please also be aware about one thing. This is ok:
a ? b() : c();
However this won't compile:
a ? b() : ; ;
;
cannot substitute for an expression; only for a statement.
The most common case is probably
int i = 0;
for (/* empty */; i != 10; ++i) {
if (x[i].bad) break;
}
if (i != 10) {
/* panic */
}
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
;
and generate no code at all for it, so it does no harm and there are situations (like macros and auto generated code) where avoiding stray semicolons would be a pain.