41

Why would someone use this?

if(a==1){;} 

There no statement, only one semicolon, and it doesn't throw an error. What purpose does this semicolon serve?

psmears
  • 26,070
  • 4
  • 40
  • 48
Nadeem Khan
  • 364
  • 3
  • 10
  • 33
    It serves no purpose. It's just an empty statement. – Algirdas Preidžius Jan 11 '17 at 14:05
  • 5
    Is this C or C++? – Bathsheba Jan 11 '17 at 14:07
  • 2
    I never tried this but wouldnt such empty statement be usefull for debugging purposes? like adding breakpoints? – marcinj Jan 11 '17 at 14:15
  • 2
    There are some use cases, e.g. `while (x.compare_exchange_weak(xexp,xexp+2.0)) ;` – metalfox Jan 11 '17 at 14:21
  • In which case, it's either unsigned behaviour or a no-op, depending on what `a` is. See my answer (which sadly suffers from a complete lack of attention). – Bathsheba Jan 11 '17 at 14:24
  • 26
    @Bathsheba unsigned behaviour? Is that what fans do when they're queuing for autographs? – Quentin Jan 11 '17 at 14:29
  • In conjunction with an else it can make conditions easier to read if(has_car && has_licence);else{...} ratheer than if(!has_car || !has_licence){...} – Malcolm McLean Jan 11 '17 at 14:29
  • 1
    @Quentin I believe that was supposed to be "undefined behavior". – Josh Sanford Jan 11 '17 at 14:30
  • 1
    @MalcolmMcLean `if(!(hasCar && hasLicence))` still looks clearer to me... – Quentin Jan 11 '17 at 14:40
  • 1
    I've seen this sort of thing appear where there's an inflexible coding standard of "every if must have an else". (A thoroughly, infuriatingly, stupid standard.) In those cases where you simply just don't need an `else`, then either the `if` or `else` must be a no-op . – Grimm The Opiner Jan 11 '17 at 15:57
  • 2
    @marcinj Nope, because it generates no assembler code, so there is not an instruction which you could breakpoint (on Windows, `asm(int 3);` would be a good idea - you don't need to set a breakpoint, but the debugger always stops there - and it does nothing when running outside of a debugger. – Mawg says reinstate Monica Jan 11 '17 at 16:00
  • @Mawg Wouldn't that be `asm("int 3");`? Or perhaps `asm((int)3);` if you're trying to pass it the number (but it would already be an `int` afaik...). – wizzwizz4 Jan 11 '17 at 18:00
  • 2
    Nope, the `int` refers to triggering an `interrupt` - see https://en.wikipedia.org/wiki/INT_%28x86_instruction%29#INT_3 – Mawg says reinstate Monica Jan 11 '17 at 18:02
  • 2
    Better for portability if, rather than using inline assembly for breakpoints, you use an intrinsic. `__debugbreak()` on MSVC. @mawg – Cody Gray - on strike Jan 11 '17 at 18:12
  • Fine and dandy - if you use MSVC :-) +1 otherwise, just inline it. Either way, it's a nice trick, which doesn't get enough publicity. I add it to error branches and don’t have to remove it for release. I can leave it there when when debugging, clear all breakpoints, set new ones, and still stop on any error branch marked such. – Mawg says reinstate Monica Jan 11 '17 at 18:16
  • 3
    It might *possibly* suppress a compiler warning about the variable `a` being unused. But more likely it’s what Stephen Jay Gould called a spandrel: a piece of code (he was talking about our genetic code) that once served a purpose in its original context, but now is just left over after the other pieces were removed. – Davislor Jan 11 '17 at 18:53
  • Partially related: http://stackoverflow.com/q/154136/5399734 – nalzok Jan 12 '17 at 02:34
  • 1
    Casting the final close vote, since 4 people already agreed this is probably a duplicate. I figured that was as good as protecting it. Either way, something needed to be done; this already has *more than enough* answers. – Cody Gray - on strike Jan 12 '17 at 10:26
  • @NadeemKhan Did one of the answers provided below answer your question? If so you should [accept one of them](http://stackoverflow.com/help/accepted-answer). – dbush Jan 12 '17 at 16:26

11 Answers11

56

It's an empty statement. A single semicolon by itself performs no operation.

In this context, it means that if the if condition is true, do nothing.

Without an else section, there is not much use to this code. If there is, then it's a matter of style whether the condition should be inverted and should contain just a non-empty if portion.

In this case it's a simple conditional, so style-wise it's probably better to invert it, however if the condition is more complicated it may be clearer to write this way. For example, this:

if ((a==1) && (b==2) && (c==3) && (d==4)) {
    ;
} else {
    // do something useful
}

Might be clearer than this:

if (!((a==1) && (b==2) && (c==3) && (d==4))) {
    // do something useful
}

Or this:

if ((a!=1) || (b!=2) || (c!=3) || (d!=4)) {
    // do something useful
}

A better example from the comments (thanks Ben):

if (not_found) {
    ;
} else {
    // do something
}

Versus:

if (!not_found) {
    // do something
}

Which method to use depends largely on exactly what is being compared, how many terms there are, how nested the terms are, and even the names of the variables / functions involved.

Another example of when you might use this is when you have a set of if..else statements to check a range of values and you want to document in the code that nothing should happen for a particular range:

if (a < 0) {
    process_negative(a);
} else if (a >=0 && a < 10) {
    process_under_10(a);
} else if (a >=10 && a < 20) {
    ;   // do nothing
} else if (a >=20 && a < 30) {
    process_20s(a);
} else if (a >= 30) {
    process_30s_and_up(a);
}

If the empty if was left out, a reader might wonder if something should have happened there and the developer forgot about it. By including the empty if, it says to the reader "yes I accounted for this and nothing should happen in this case".

Certain coding standards require that all possible outcomes be explicitly accounted for in code. So code adhering to such a standard might look something like this.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 10
    I disagree with the `might be cleaner than this`. I know it's opinionated but at least for me it's much easier to read the code as `if none of these, do this` instead of `if this and this and this and this do nothing else do this` – Bauss Jan 11 '17 at 14:25
  • 21
    This would all apply without the semicolon. – juanchopanza Jan 11 '17 at 14:52
  • 1
    All of those options are terrible. If the condition is that complex it should be extracted to a well-named function. – BlueRaja - Danny Pflughoeft Jan 11 '17 at 15:20
  • 4
    Concrete example where it might be clearer to write this way: consider a flag variable with a negative in the name, such as "not_found". It's probably clearer to do "if (not_found) {;} else { ... }" than to have a double negative "if (!not_found) {...}" – Ben Jan 11 '17 at 15:28
  • @BlueRaja: if you extract a complex condition to a well-named function, you will just move the problem to the function: what code will you write there? Sooner or later you will have to deal with the complex condition. At that point you will have to make a choice: which of the options presented here is better? They might all be terrible, but you will have to choose one eventually. – Fabio says Reinstate Monica Jan 11 '17 at 15:59
  • @Ben that's why you should have coding guidlines that _discorage_ the use of negatives in variable names. For your example, it would be much clearer for the variable to be named `found` and have inverse boolean values to your `not_found`. – Baldrickk Jan 11 '17 at 16:01
  • `!not_found` -> `found`?? – iceman Jan 11 '17 at 16:46
  • 2
    @FabioTurati: With respect to what we're talking about, `if(!(complex_condition)){ /*stuff*/ }` vs. `if(complex_condition) {} else { /*stuff*/ }`, no, you wouldn't. You'd have a function that does `return (complex_condition)` at which point the horrible second-option becomes unnecessary. – BlueRaja - Danny Pflughoeft Jan 11 '17 at 16:55
  • 6
    I'm aware of only one case in which `;` is absolutely necessary. One needs to put it after `goto` labels if the next token after them is `}`: `label: }` wont work, but `label: ; }` will. – HolyBlackCat Jan 11 '17 at 19:29
  • In your `if`/`else if` example, it might be clearer if the final section is an `else`. Of course, if you're going for clarity, than this sort of empty statement would be one of the first things to go. – krillgar Jan 11 '17 at 20:10
  • 1
    I think the last example is perhaps the best one, though as written all the tests after the first include a redundant term. What's important is that having the positive case on the third test "do nothing" makes the "none-of-the-above" case read like a negative-fall-through cases for the original if-elseif chain, rather than being a fall-through case within the third `if`'s positive case. – supercat Jan 11 '17 at 21:03
  • @BlueRaja-DannyPflughoeft I absolutely agree - there are two huge great advantage of moving the logical condition into a separate function: (1) you can put it somewhere else in the code - preferably in a completely different file with a hard-to-guess name. Ideally, you should also give it the same overloaded name as 20 other similar functions, just to make it easier for the next programmer to figure out what's going on; (2) if your manager measures "productivity" by counting lines of code, doing that just increased your productivity! (Irony intentional, of course) – alephzero Jan 11 '17 at 23:33
  • if should always comes with else. – GeneCode Jan 12 '17 at 03:14
  • 1
    A flag variable named `not_found` is a bad code smell. – Wouter Lievens Jan 12 '17 at 09:34
  • 1
    `int usefulStuffAlreadyDone = (a==1) && (b==2) && (c==3) && (d==4); if(!usefulStuffAlreadyDone) { /* usefull stuff */ }` -- problem solved: no null statements and no awkward inversions. – CompuChip Jan 12 '17 at 10:22
44

It's called null statement.

From 6.8.3 Expression and null statements:

A null statement (consisting of just a semicolon) performs no operations.

In this particular example if(a==1){;}, it doesn't do anything useful (except perhaps a bit more obvious) as it's same as if(a==1){} or if(a==1);.

P.P
  • 117,907
  • 20
  • 175
  • 238
18

No purpose at all. It's an empty statement. It's possible that the developer wanted to do something if a was not 1 in which case the code would be something like (even though the ; can still be omitted) :

if(a==1)
{
  ;
}
else
{
  //useful code...
}

But in that case, it could've easily been written as if(a != 1).


Note however, if this is C++(tags aren't clear yet) then there would be a possibility that the operator== of type a was overloaded and some side effects could've been observed. That would mean that the code is insane though.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
13

It is so called null statement. It is a kind of the expression statement where the expression is missed.

Sometimes it is used in if-else statements as you showed when it is easy to write the if condition than its negation (or the if condition is more clear) but the code should be executed when the if condition is evaluated to false.

For example

if ( some_condition )
{
   ; // do nothing
}
else
{
   // here there is some code
} 

Usually the null statement is used for exposition only to show that for example body of a function, or a class constructor or a for loop is empty. For example

struct A
{
    A( int x ) : x( x )
    {
        ;
    }

    //...
};

Or

char * copy_string( char *dsn, const char *src )
{
    char *p = dsn;

    while ( ( *dsn++ = *src++ ) ) ;
                                 ^^^
    return p;
}

Here the null statement is required for the while loop. You could also rewrite it like

    while ( ( *dsn++ = *src++ ) ) {}

Sometimes the null statement is required especially in rare cases when goto statement is used. For example in C declarations are not statements. If you want to pass the program control to a point before some declaration you could place a label before the declaration. However in C a label may be placed only before a statement. In this case you could place a null statement with a label before the declaration. For example

Repeat:;
      ^^^
    int a[n];

    //....

    n++;
    goto Repeat;

Pay attention to the null statement after the label. If to remove it then the C compiler will issue an error.

This trick also is used to pass the program control to the end of a compound statement. For example

{
   // some code
    goto Done;
   //...

   Done:;
}

Though you should not use the goto statement but you should know about these cases.:)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
8

As so many have said - it does nothing.

Why is it there? Here is a possibility …

I am fed up with bad coders on my team not checking return values of functions.

So, since we develop in Linux with the GCC compiler, I add __attribute__((warn_unused_result)) to the declaration of all of my typed functions. See also this question for a MS VC equivalent.

If the user does not check the return value, then the compiler generates a warning.

The cowboys, of course, have gamed the system and code if (foo() != SUCCESS) ; which satisfies the compiler (although it does not satisfy me :-).

Community
  • 1
  • 1
Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
  • OP asked about the utility of the semicolon, not of that of the `if` clause. – Marc van Leeuwen Jan 12 '17 at 08:40
  • Why pick on me? :-) Seriously, all other answer are using `if`. Look at nwellnhof's currently directly below this ... `often used in long if/else chains` and others. Vlad’s below that ` used in if-else statements` , etc, etc, etc I do understand that we can use a semic as standalone statement `i++; /*here it comes*/ ; /* what was that for? */ j++;`, but the OP didn't phrase it that way, so I sought to explain it ***in the context of the question*** (as did all the others) while also teaching a much underused pragma. – Mawg says reinstate Monica Jan 12 '17 at 08:47
7

A single ; is the null statement which does nothing. It's often used in long if/else chains like:

if (a == 1) {
    // Do nothing.
    ;
}
else if (...) {
    ...
}
else if (...) {
    ...
}

This could also be written as:

if (a != 1) {
    if (...) {
        ...
    }
    else if (...) {
        ...
    }
}

The latter adds another level of indentation but IMO, it's clearer. But null statements can sometimes be useful to avoid excessive indentation if there are multiple branches without code.

Note that an empty compound statement (also called block) has the same effect:

if (a == 1) {}

Technically, you only need the semicolon if you want to use an expression statement directly:

if (a == 1) ;
else if (...) { ... }
else if (...) { ... }

So writing {;} is redundant and only serves a dubious illustrative purpose.

Another example from the C standard where the null statement is used to supply an empty loop body:

char *s;
/* ... */
while (*s++ != '\0')
    ;

But here I'd also prefer an empty compound statement.

nwellnhof
  • 32,319
  • 7
  • 89
  • 113
  • If one of the intermediate items in the chain would have an empty body, I'd code would be more readable using a consisent `if`/`else if` pattern than it would be if it inverted the logic on the empty-body case and moved everything from its "else" case to its "true" case. – supercat Jan 11 '17 at 21:05
4

It is basically an null/empty statement, which does nothing, and is as expected benign (no error) in nature.

C Spec draft N1570 clarifies that:

  1. the expressions are optional: expression[opt] ;
  2. A null statement (consisting of just a semicolon) performs no operations.

On the other hand, Bjarne quotes in his C++ book #9.2 Statement Summary:

A semicolon is by itself a statement, the empty statement.

Note that these two codes, if(1) {;} and if(1) {}, have no difference in the generated gcc instructions.

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
  • You only show the generated code for one of them? I wonder why the compiler generated a nop? Presumably for alignment of the following stamen? – Mawg says reinstate Monica Jan 12 '17 at 08:03
  • 1
    No, the nop isn't for alignment. It's because this was compiled without optimization enabled, which makes the whole thing rather meaningless. The compiler doesn't care about alignment when optimizations are disabled. It emits a nop when optimization is disabled to facilitate your setting a breakpoint on that line of code. If you're going to post answers that analyze the disassembly, it needs to be of optimized code, otherwise it's misleading and a waste of everyone's time. (cc @mawg) – Cody Gray - on strike Jan 12 '17 at 10:25
  • I see. I see. T'was but a mere guess. Thansk for justifying the `NOP`; that is interesting. Is it a trick that I can rely on? (althoguh I still prefer `asm(int 3)`? – Mawg says reinstate Monica Jan 12 '17 at 10:38
  • Yes that shows only one of them, but `;` can be easily commented out to see if there is any effect. – Saurav Sahu Jan 12 '17 at 10:55
4

; on its own is an empty statement. If a is an initialised non-pointer type, then

if(a==1){;}

is always a no-op in C. Using the braces adds extra weight to the assertion that there is no typo. Perhaps there is an else directly beneath it, which would execute if a was not 1.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

Why would you do it? I do similar things all the time when debugging to give me something that (I hope) won't be optimized away so I can put a break point on it.

Normally though I make it obvious its a debug mark

if( (a==1) && (b==2) && (c==3) && (d==4) ){

  int debug=1;

}

Otherwise I end up with weird little bits of code stuck everywhere that make absolutely no sense even to me.

But that is not guarantee that's what this was.

Brenton Thomas
  • 618
  • 1
  • 7
  • 17
0

; is an empty statement noop

What is its purpose?

Sometimes we just want to compare things like in this case the equality of a and 1. With primitive types like integer, this will set condition register so if you have after this if something like if(a > 1) or if(a < 1), and a is not changed in the meantime, this might not be evaluated again depending on the compiler decision.

This code

 int f(int a){
        if(a == 1){;}
        if(a > 1){return 3;}
        if(a < 1){return 5;}

        return 0;
 }

will give

.file   "c_rcrYxj"
.text
.p2align 2,,3
.globl  f
.type   f, @function
f:
.LFB0:
    .cfi_startproc
    cmpl    $1, 4(%esp)
    jle .L6
    movl    $3, %eax
    ret
    .p2align 2,,3
.L6:
    setne   %al
    movzbl  %al, %eax
    leal    (%eax,%eax,4), %eax
    ret
    .cfi_endproc
 .LFE0:
.size   f, .-f
.ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section    .note.GNU-stack,"",@progbits

The comparison is done only once cmpl $1, 4(%esp), exactly where if(a==1) is written.

0

You probably already know that the semicolon is an empty statement. Concerning the actual question "what purpose does this semicolon serve", the answer is (unless the author of this code wanted to enliven the code with some weird emoticon), that it serves absolutely no purpose at all. That is, {;} is completely equivalent to {} in any context (where a statement is expected, which I think is the only place where {;} can be used). The presence of the semicolon changes a compound statement with 0 constituent statements into a compound statement with 1 constituent statement which is an empty statement, but the two cases are equivalent as far as semantics is concerned.

I'll add a personal opinion that for readability concern of not being accidentally overlooked by a reader of the code, {;} is no better than {} (if it were, then maybe {;;;;;;;;} would be better still), though both are considerably better than a lone ; (and as a consequence the language would have been better off without allowing ; as empty statement at all, since replacing it with {} is always advantageous).

Marc van Leeuwen
  • 3,605
  • 23
  • 38