2

My question is that does it matter if I declare a variable outside the loop and reinitialize every time inside the loop or declaring and initializing inside the loop? So basically is there any difference between these two syntaxes (Performance,standard etc)?

Method 1

int a,count=0;
while(count<10)
   a=0;

Method 2

int count=0;
while(count<10)
   int a=0;

Please assume that this is only a part of a bigger program and that the body inside loop requires that the variable a have a value of 0 every time. So, will there be any difference in the execution times in both the methods?

haccks
  • 104,019
  • 25
  • 176
  • 264
Pranav Jituri
  • 823
  • 1
  • 11
  • 25
  • 2
    In 2nd case, your variable `a` will not be available outside loop. – Hanky Panky Dec 21 '13 at 15:02
  • @Hanky웃Panky - Fair Enough as the loops have scope to the immediate next line only. But, I am not clear whether there will be any difference in performance in both the methods? – Pranav Jituri Dec 21 '13 at 15:04
  • @PranavJituri; What performance? – haccks Dec 21 '13 at 15:05
  • @haccks - Like will there be any difference in the execution times of both the loops? Assume that rest of the body requires that the variable A is initialized to `0` everytime? – Pranav Jituri Dec 21 '13 at 15:06
  • 2
    No, there will be no performance difference at all. –  Dec 21 '13 at 15:07
  • @PranavJituri; I can't say anything about this. I do not have much idea on performance. – haccks Dec 21 '13 at 15:09
  • `as the loops have scope to the immediate next line only` this is wrong assumption. It will only happen in this case because your loop has 1 line block. If it had `{}` with multiple lines that span would be there for all those lines – Hanky Panky Dec 21 '13 at 15:09
  • 4
    There may be a performance difference, BUT it wouldnt appear unless your loop runs billions of times AND in all likelihood the compiler would optimize it out anyway. Dont sweat the small performance concerns. The issue of scope mentioned below is much more important. – tHand Dec 21 '13 at 15:13
  • 2
    I think that method 2 only works in `C++` and not in `C`. – Sam Dec 21 '13 at 15:35
  • 1
    @SAM; Will work in C if you place braces around the `while` body. – haccks Dec 21 '13 at 15:36
  • @haccks Ohh.. thanks.. +1.. I just checked it... But why is that so? – Sam Dec 21 '13 at 15:51
  • @SAM; Read Jonathan's comment on my answer. – haccks Dec 21 '13 at 15:55
  • see also the duplicates [7959573](http://stackoverflow.com/questions/7959573/declaring-variables-inside-loops-good-practice-or-bad-practice-2-parter), [982963](http://stackoverflow.com/questions/982963/is-there-any-overhead-to-declaring-a-variable-within-a-loop-c) [407255](http://stackoverflow.com/questions/407255/difference-between-declaring-variables-before-or-in-loop) etc. – craq May 13 '14 at 12:09

4 Answers4

5

Yes, it does matter. In second case

int count=0;
while(count<10)
   int a=0;

a can't be referenced out side of while loop. It has block scope; the portion of the program text in which the variable can be referenced.
Another thing that Jonathan Leffler pointed out in his answer is both of these loops are infinite loop. And second, the most important second snippet would not compile without {} (in C) because a variable definition/declaration is not a statement and cannot appear as the body of a loop.

 int count  =0;
 while(count++ < 10)
 {  
      int a=0;  
 } 
Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    Note that a variable definition/declaration is not a statement and cannot have a label prefixed to it or appear as the body of a loop. It would work OK if there were braces around the body of the loop; the braces make a single block and a variable definition is allowed within the block. – Jonathan Leffler Dec 21 '13 at 15:17
  • @JonathanLeffler; Got it. – haccks Dec 21 '13 at 15:33
  • @haccks - My basic question is still not answered (although I learnt other things as well which is good), the question being whether there will be any `PERFORMANCE` difference between those two loops or not(say I run it a billion times)? – Pranav Jituri Dec 21 '13 at 15:39
  • I already said that I do not have much idea but guessing that for billion times loop first would be better. Because in second case there is unnecessarily `a` is declared on each iteration. – haccks Dec 21 '13 at 15:43
  • 3
    @PranavJituri: there will be a marginal cost to setting the variable `a` to `0` on each iteration of the loop. Whether that's measurable or not is doubtful; it certainly isn't a good reason to worry about it. Now, if instead of being a simple `int` (that might be in a register), the value was an array of 1000 elements that had an initializer for the 37th element (and therefore zeroed the other 999 elements), then there'd be a cost that would be both measurable and worth worrying about. – Jonathan Leffler Dec 21 '13 at 17:21
  • @JonathanLeffler - Hmm. Got it. There will be very minute performance issue in both the cases. I guess this resolves it :) – Pranav Jituri Dec 21 '13 at 17:32
3

This

void f1(void)
{
  int a, count = 10;
  while (count--)
    a = 0;
}

void f2(void)
{
  int count = 10;
  while (count--)
  {
    int a = 0;
  }
}

results in this (using non optimising gcc (Debian 4.4.5-8) 4.4.5):

.globl f1
        .type   f1, @function
f1:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        movl    $10, -4(%rbp)
        jmp     .L2
.L3:
        movl    $0, -8(%rbp)
.L2:
        cmpl    $0, -4(%rbp)
        setne   %al
        subl    $1, -4(%rbp)
        testb   %al, %al
        jne     .L3
        leave
        ret
        .cfi_endproc
.LFE0:
        .size   f1, .-f1
.globl f2
        .type   f2, @function
f2:
.LFB1:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        movl    $10, -8(%rbp)
        jmp     .L6
.L7:
        movl    $0, -4(%rbp)
.L6:
        cmpl    $0, -8(%rbp)
        setne   %al
        subl    $1, -8(%rbp)
        testb   %al, %al
        jne     .L7
        leave
        ret
        .cfi_endproc
.LFE1:
        .size   f2, .-f2

The assembly code looks quiet the same.

alk
  • 69,737
  • 10
  • 105
  • 255
  • I bet it wouldn't look the same if you added braces, and possibly a printf outside the while loop – Elias Van Ootegem Dec 21 '13 at 16:32
  • @EliasVanOotegem: "*Braces*"? Where? Around the `a = 0;`? Surely the assembly will be the same. A `printf()` printing what and where? – alk Dec 21 '13 at 16:50
  • sorry, still a tad hung over probably... mistook `while() a = 0;` for `while() int a = 0;` never mind. Still, if you're not accessing the variable after the loop, and the function returns straight away, surely you won't see a difference in the asm, because the function + block scope are GC'ed at the same time, why not add an assignment after the while in both cases, see if the resulting asm still matches – Elias Van Ootegem Dec 21 '13 at 16:59
  • @EliasVanOotegem: "*... add an assignment ...*" to what please? `a` is out of scope after the `while`-loop in the 2nd exmaple. And touching `count` whouldn't change anything. – alk Dec 21 '13 at 17:09
  • Exacyly: if the asm looks the same, that's because the compiler translated both functions to the same thing, if you add an assignment to count after the while block in the second example, the resulting asm code should show a difference, in theory, `a` should be deallocated prior to the last assignment to `count` in that case – Elias Van Ootegem Dec 21 '13 at 17:14
  • @EliasVanOotegem: Fair enough.... |-) So let me correct the wording of my last comment to be: "*And touching count whouldn't change anything **relevant**!*" – alk Dec 21 '13 at 17:20
1

The first compiles; the second doesn't. The first runs for a very long time.

If the second was:

int count = 0;
while (count++ < 10)
{
    int a = 0;
    ...do something with a...
}

and you also made similar changes and did something with a in the first loop, then the difference is that a is set to zero on each iteration of the loop in the second case, but it holds whatever value it is set to in the loop in the first case. Also, in the second case, the variable a does not exist outside the loop and cannot therefore be referenced after the loop.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 3
    It's not my downvote, but most of your answer seems to focus on the specific (admittedly flawed) example OP gave rather than the more general underlying question. –  Dec 21 '13 at 15:06
  • 2
    There is a downvoting race (without comment) on SO these days! – haccks Dec 21 '13 at 15:08
  • 1
    @delnan: thanks for the commentary. I see three-and-a-bit full lines of text addressing the correct general case code, and one brief line outlining the flaws in the question as asked. I'm not sure what the balance should be changed to. – Jonathan Leffler Dec 21 '13 at 15:08
  • @delnan I have edited my question and added a bit more explaination. Is that enough or are there some other flaws to it as well? Please explain :) – Pranav Jituri Dec 21 '13 at 15:10
  • 1
    I do not see any wrong with this answer. I think it is the complete answer. +1 – haccks Dec 21 '13 at 15:12
  • 1
    In fact this answer takes into account the infinite loop issue in the snippet provided by OP. This is not flawed but correct. – haccks Dec 21 '13 at 15:19
0

yes in your 1st method it is zero for next of your bigger program.

while in your method 2 the same 'a' cannot be accessed in further statements. if so would produce an error as undefined reference to variable 'a'. it would be zero for that loop life but is nothing after the loop. you can again define variable 'a' after that while loop.

vinayawsm
  • 845
  • 9
  • 28