What are typical uses of null statement
;
in C ?
I know that it is basically used to skip expression where it is expected
I have used it, albeit rarely, in a possibly unusual situation (and one that some/many people would find wrong). I have had to sometimes write a very complex if
condition without an else
clause where the if condition has to be negated. Obviously it can be something like this:
if ( !( overly complex condition ) )
{
do stuff
}
It sometimes makes more sense (to me at least) to think of it in terms of positive logic. In other words, if the overly complex condition
holds true, I don't want the code to run. So I have instead written it as:
if ( overly complex condition )
; // do nothing
else
{
do stuff
}
I can think of scanf
validation. scanf
gets stuck when user didn't give the correct input. So, to prevent scanf
from being stuck, characters until end of line must be removed.
if( scanf("%d",&integer) == 0 )
{
while( getchar() != '\n' ) ;
// ....
}
A somewhat unusual use -- but for which I really appreciate the existence of the null statement -- is when I have two conditions and two actions which I find I can most naturally express like this:
if(condition1)
/* do nothing */ ;
else if(condition2)
do_something;
else do_something_else;
Often condition1
tests that everything is okay, but if it's not, condition2
distinguishes between two different exception actions do_something
and do_something_else
.
This isn't the only way to express such a thing, of course. It would be possible to repeat condition1
:
if(!condition1 && condition2)
do_something;
else if(!condition1)
do_something_else;
But that seems inferior, because it repeats condition1
. Or it would be possible to use nested if
statements:
if(!condition1) {
if(condition2)
do_something;
else do_something_else;
}
But of course nested if
statements are notoriously prone to overcomplication and obfuscation, too. So I often prefer the first version, with the null statement.
Unit tests for a compliant compiler.
while (*(dst++) = *(src++))
;
After a label at the end of a function (or more precisely, at the end of any block), e.g.
void foo(void)
{
// ...
exit:
;
}