3

I just want to be sure that this C code:

while(flag==true)
{
} 
foo();

does the same as this:

while(flag==true);

foo();
Suraj Jain
  • 4,463
  • 28
  • 39

6 Answers6

9

; alone is a null statement in C.

In your case, {} or ; are syntactically needed, but they do the same: nothing

Related: Use of null statement in C

Community
  • 1
  • 1
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
3

In addition to the other answers: It's the same thing.

But I prefer this:

while (condition)
{
} 
foo();

over this:

while (condition);
foo();

because if you forget the semicolon after the while, your code will compile fine but it won't do what you expect:

while(condition)  // ; forgotten here
foo();           

will actually be equivalent of:

while(condition)
{
  foo();
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • FYI: Recent gcc warns about this. I think it is the same as with Yoda-conditions: once they had their use, but now they just make the code less clear. You don't answer the question, but just state your personal opinion. – too honest for this site Mar 01 '17 at 14:52
  • @Olaf Using braces instead of a semi colon at the end is indeed good practice. Alternatively `while (condition) < new line > ;` is fine too. Harsh down vote, this is the best answer posted. The answer is also backed up by MISRA-C:2012 15.6 so this isn't just someone's subjective opinions. MISRA-C is in turn mostly based on scientific research, most notably by Les Hatton, who's work was published in the book _Safer C_. The semicolon issue is listed in said book, 2.7 Empirically Determined Misbehavior. This is a known source of bugs, proven by population studies of C code. – Lundin Mar 01 '17 at 15:28
2

Yes, having an empty body of the loop is equivaled to just while(<some condition>);

Gnqz
  • 3,292
  • 3
  • 25
  • 35
2

Yes. A ; following a control structure (e.g., while, for, etc.) that can be followed with a block is treated as if it was followed by an empty block.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
2

Yes, because when put semicolon after while loop statement that indicate empty body and when the condition becomes false then it goes to the immediate next statement after that loop. 

msc
  • 33,420
  • 29
  • 119
  • 214
2

Yes, they are same.

You Can Generate The assembly of the code and see for yourself that they produce the same assembly. (Using gcc filename.c -S -masm=intel -o ouputfilename)

#include<stdio.h>

int foo(void);
int main(){

  int flag;
  scanf("%d" , &flag);
  while(flag==1);
  foo(); 
}


int foo(void){
  int x = 2;
  return x*x;
}

.LC0:
    .ascii "%d\0"
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    push    rbp
    .seh_pushreg    rbp
    mov rbp, rsp
    .seh_setframe   rbp, 0
    sub rsp, 48
    .seh_stackalloc 48
    .seh_endprologue
    call    __main
    lea rax, -4[rbp]
    mov rdx, rax
    lea rcx, .LC0[rip]
    call    scanf
    nop
.L2:
    mov eax, DWORD PTR -4[rbp]
    cmp eax, 1
    je  .L2
    call    foo
    mov eax, 0
    add rsp, 48
    pop rbp
    ret
    .seh_endproc
    .globl  foo
    .def    foo;    .scl    2;  .type   32; .endef
    .seh_proc   foo
foo:
    push    rbp
    .seh_pushreg    rbp
    mov rbp, rsp
    .seh_setframe   rbp, 0
    sub rsp, 16
    .seh_stackalloc 16
    .seh_endprologue
    mov DWORD PTR -4[rbp], 2
    mov eax, DWORD PTR -4[rbp]
    imul    eax, DWORD PTR -4[rbp]
    add rsp, 16
    pop rbp
    ret
    .seh_endproc
    .ident  "GCC: (x86_64-posix-seh-rev1, Built by MinGW-W64 project) 6.3.0"
    .def    scanf;  .scl    2;  .type   32; .endef

And When I Changed while(flag == 1); to while(flag==1){} Assembly Code Generated is :


.LC0:
    .ascii "%d\0"
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    push    rbp
    .seh_pushreg    rbp
    mov rbp, rsp
    .seh_setframe   rbp, 0
    sub rsp, 48
    .seh_stackalloc 48
    .seh_endprologue
    call    __main
    lea rax, -4[rbp]
    mov rdx, rax
    lea rcx, .LC0[rip]
    call    scanf
    nop
.L2:
    mov eax, DWORD PTR -4[rbp]
    cmp eax, 1
    je  .L2
    call    foo
    mov eax, 0
    add rsp, 48
    pop rbp
    ret
    .seh_endproc
    .globl  foo
    .def    foo;    .scl    2;  .type   32; .endef
    .seh_proc   foo
foo:
    push    rbp
    .seh_pushreg    rbp
    mov rbp, rsp
    .seh_setframe   rbp, 0
    sub rsp, 16
    .seh_stackalloc 16
    .seh_endprologue
    mov DWORD PTR -4[rbp], 2
    mov eax, DWORD PTR -4[rbp]
    imul    eax, DWORD PTR -4[rbp]
    add rsp, 16
    pop rbp
    ret
    .seh_endproc
    .ident  "GCC: (x86_64-posix-seh-rev1, Built by MinGW-W64 project) 6.3.0"
    .def    scanf;  .scl    2;  .type   32; .endef

You can see that the relevant portion is same in both cases.

 //Below Portion is same in both cases. 
.L2:        
    mov eax, DWORD PTR -4[rbp]
    cmp eax, 1
    je  .L2
    call    foo
    mov eax, 0
    add rsp, 48
    pop rbp
    ret
    .seh_endproc
    .globl  foo
    .def    foo;    .scl    2;  .type   32; .endef
    .seh_proc   foo
Suraj Jain
  • 4,463
  • 28
  • 39