2

Is there a difference in C++ between the following, with regards to the amount and efficiency in space and time utilisation, and does the answer depend on the compiler?

int main() {
    int a, b = 0;
    doSomething1(b);
    a = 9;
    doSomething2(a);
    return 0;
}
int main() {
    int a = 0, b = 0;
    doSomething1(b);
    a = 9;
    doSomething2(a);
    return 0;
}
int main() {
    int b = 0;
    doSomething1(b);
    int a = 9;
    doSomething2(a);
    return 0;
}

Edit: This question has been marked as a duplicate of this, which in my opinion is incorrect because

  1. The other question is asking if variables - regardless of where they are used in a function - should be declared at the very start, or if they should be declared only within the code block where it is used (i.e. the most local scope).
  2. My question is asking if there is a performance difference, space- or time-wise, to initializing variables at the very start of a function, or only at the point where it is needed in the same scope.

Please review the flag on this question. It's not a duplicate.

Community
  • 1
  • 1
thegreatjedi
  • 2,788
  • 4
  • 28
  • 49
  • 1
    If you read the answers in the duplicate question it (in my opinion) appears to answer your question. The point of the duplicate banner is not to say the 2 questions are exactly the same but that the answers to the duplicate question also serve as answers to this question. – IKavanagh Dec 08 '15 at 09:56
  • Did you try once to look into the generated code (by your *optimizing* compiler)? – Basile Starynkevitch Dec 08 '15 at 10:01

1 Answers1

2

In principle, any C++11 conforming implementation should show equivalent behavior (and what "equivalent" means is difficult to grasp, the tricky notion being : undefined behavior).

In practice, I believe that it is better to initialize every variable at (or near) its declaration (like your second example). The code is probably easier to read and will show more deterministic behavior.

With recent GCC, when compiling with g++ -std=c++11 -Wall -Wextra -g, you'll get useful warnings about uninitialized variables.

Regarding performance, when asked to optimize (e.g. g++ -std=c++11 -O2) the compiler will remove useless initializations - notably for local variables - (hence always initializing variables does not practically impact the performance of generated code).

My question is asking if there is a performance difference, space- or time-wise, to initializing variables at the very start of a function, or only at the point where it is needed in the same scope

Probably no practical difference in performance, but the C++11 standard does not care much about performance (and care much more about compliance). Performance is a quality of implementation issue.

If you care that much about performance, you'll need to benchmark. But don't forget to enable optimizations in your compiler (e.g. g++ -march=native -O2); I guess you won't be able to notice any significant performance difference (so, if you measure reliably some difference, it probably would be a small fraction of percent).

Please look inside the generated assembler code (e.g. with g++ -S -fverbose-asm -O2, then look into the *.s generated assembler file). With GCC you might also pass -fdump-tree-all to get hundreds of dump files explaining what optimizations happened (but you'll spend days in studying them).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Performance-wise, is there a difference between first and third main() with respect to the difference of when a is declared? – thegreatjedi Dec 08 '15 at 09:34
  • I'm surprised that g++ can remove useless initialization: how does g++ know it's useless (unless it's a non-exported symbol?). Do you have more info on that? – qdii Dec 08 '15 at 09:46
  • It is implementation specific and depends upon the optimizations you enabled in the compiler. But most optimizing compilers will generate code with similar performance – Basile Starynkevitch Dec 08 '15 at 09:46
  • @thegreatjedi Basile knows probably more about that than I do, but I'd be very surprised if there were a difference. The two possibilities where one could arise are: (1) `a`'s unused initialization to zero will be optimized away. Compilers are good these days to catch code with no effect. (@qdii: It's a local variable and not visible anywhere else.) (2) The stack's size may be adjusted again in the middle of the function to accomodate `a`, as opposed to the first example where the stack is allocated at once for good. (Is that what you fear?) It would be extremely cheap, if it happens at all. – Peter - Reinstate Monica Dec 08 '15 at 09:51