Use of null statement in C

c
14,517

Solution 1

It's typically the side-effect of a code block that was stripped by the preprocessor, like

#if DEBUG
    #define ASSERT(_x) Assert(_x)
#else
    #define ASSERT(_x)
#endif


ASSERT(test);    // Results in null statement in non-debug builds

That, or in loops where your condition already contains whatever needs to be done in each iteration.

Solution 2

while (*(dst++) = *(src++))
    ;

Solution 3

After a label at the end of a function (or more precisely, at the end of any block), e.g.

void foo(void)
{
    // ...

exit:
    ;
}

Solution 4

while (somethingWithSideEffects()) ;

Solution 5

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
  }  
Share:
14,517

Related videos on Youtube

Agnius Vasiliauskas
Author by

Agnius Vasiliauskas

Truth is this - don't believe to those who says :  Truth is this - don't believe to those who says :   Truth is this - don't believe to those who says :    Truth is this - don't believe to those who says :     Truth is this - don't believe to those who says :      Tru...

Updated on March 25, 2022

Comments

  • Agnius Vasiliauskas
    Agnius Vasiliauskas about 2 years

    What are typical uses of null statement

    ;
    

    in C ?

    I know that it is basically used to skip expression where it is expected by the compiler, but here I'm interested only in real-world examples of such use cases.

    • Steve Jessop
      Steve Jessop about 13 years
      I prefer {} if you need an empty statement, it looks to me less likely to be accidental. So "never" ;-)
    • R.. GitHub STOP HELPING ICE
      R.. GitHub STOP HELPING ICE about 13 years
      {} is not useful in some of the contexts ; would be useful in.
    • Steve Jessop
      Steve Jessop about 13 years
      @R..: which ones? As an empty statement, I mean - we've already got that in for statements you might write (; or ;;, and since the parts omitted aren't statements (rather declarations or expressions), {} won't do. Obviously there are places in C where you can't just replace a semi-colon with {}. Almost all of them. But that's not what I meant :-)
  • Steve Jessop
    Steve Jessop about 13 years
    I would totally put return; instead.
  • Steve Jessop
    Steve Jessop about 13 years
    Technically that's not a null statement. 6.8.3 of C99 defines a null statement as an expression-statement with no expression, whereas this is an iteration-statement with fewer than 3 of its optional expression s. The three things in the parentheses of a for loop aren't statements, they're semi-colon-separated expressions, which is why you can't write for(int i=10; i--; {}) Nit-picky, I know :-)
  • ikegami
    ikegami about 13 years
    @Steve Jessop, I did say it wasn't a null statement, but thanks for the extra technical details.
  • ikegami
    ikegami about 13 years
    I find it's better to break it down into multiple if. It's still going to be complex if you remove the !( ).
  • Jim Balter
    Jim Balter about 13 years
    @steve The label can come at the end of any block, so return isn't always appropriate. An example is a multiply nested loop when you want to continue an outer loop from within inner loop (of course, you could use label: continue; } instead of label: ;}).
  • Steve Jessop
    Steve Jessop about 13 years
    @Jim: or you could write continue; instead of goto label;. I believe there are uses for this, possibly even ones less crazy than, "I go to the label defined by some macro, hence I can't substitute continue in one special case". I just don't think I've ever seen one.
  • Jim Balter
    Jim Balter about 13 years
    @Steve Please read what I wrote again: "continue an outer loop from within inner loop" -- just writing continue; would continue the wrong loop. The Bliss language had no goto but did have loop labels for break/continue of outer loops; too bad C doesn't have that.
  • Steve Jessop
    Steve Jessop about 13 years
    @Jim: OK, I see. Yes, continuing an outer for loop requires a do-nothing statement. Loop labels are very rarely missed, but on the occasions when you do want one it's particularly annoying they aren't there, since it leads to silly arguments whether you should refactor into extra functions to avoid using "goto".
  • vinc17
    vinc17 over 7 years
    There is a typo in the example: Assert(x) should be replaced by Assert(_x) since _x has been used as the parameter name (I can't edit the answer as edits must be at least 6 characters).
  • vinc17
    vinc17 over 7 years
    Also, for the #else case, I would rather use #define ASSERT(_x) ((void) 0) so that an error be reported when one forgets a semicolon, such as in: ASSERT(test1) ASSERT(test2); But in this case, there isn't a null statement any longer.