10

I am trying to decide between several possible practices. Say, my function has a number of if() blocks, that work on data, that is unique to them.

  • Should I declare and initialize the local (for the block) data inside the block? Does this have runtime performance cost (due to runtime allocation in the stack)?

  • Or should I declare and/or initialize all variables at function entry, so that is is done in one, possibly faster, operation block?

  • Or should I seperate the if() blocks in different functions, even though they are only a couple of lines long and used only one in the program?

Or am I ovelooking another, cleaner, option? Is the question even answerable in it's current, general form?

Vorac
  • 8,726
  • 11
  • 58
  • 101

5 Answers5

10

Should I declare and initialize the local (for the block) data inside the block?

Absolutely: this tends to make programs more readable.

Does this have runtime performance cost (due to runtime allocation in the stack)?

No: all allocations are done upfront - the space on the stack is reserved for variables in all branches upon entering a function, not when the branch is entered. Moreover, this could even save you some space, because the space allocated for variables in non-overlapping branches can be reused by the compiler.

Or should I declare and/or initialize all variables at function entry, so that is is done in one, possibly faster, operation block?

No, this is not faster, and could be slightly more wasteful.

Or should I seperate the if() blocks in different functions, even though they are only a couple of lines long and used only one in the program?

That would probably have a negative impact on readability of your program.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Could you please provide source and/or explanation on the claim "all allocations are done upfront". I was beginning to think that C is small and boring language, but am changing my mind now! – Vorac Apr 19 '13 at 10:44
  • 1
    To be more precise, such allocations and initializations are done however the compiler decides is most efficient. – Stephen Canon Apr 19 '13 at 10:47
  • I am under the impression, and this conflicts **mohit**'s answer, that a local variable being in scope and being previously initialized, does not mean that there is allocated space for it i.e. the compiler reuses freely space of varaibles, that are no longer referred until the end of the variable's scope. – Vorac Apr 19 '13 at 10:50
  • 3
    @Vorac There's no contradiction here - all he says that the compiler can be smart enough to figure out non-overlapping scopes, and reuse memory even without you putting the declarations in non-overlapping blocks. That's why I carefully said "could save", rather than "will save" in my answer. – Sergey Kalinichenko Apr 19 '13 at 10:54
4

It's a good practice to keep the scope of the variable as small as possible.
If you declare all the variable one time at the beginning, and you don't use
them often in your program. It's no use, it takes more memory.

Also, another advantages of keeping the scope small is that you can reuse
the same names again. (you don't have to invent new names each time you
do something trivial).

mohit
  • 5,696
  • 3
  • 24
  • 37
0

Out of the options you are stating, declare and initialize the local (for the block) data inside the block is what will serve your purpose. Forget the rest of the things.

0

For completeness; another, usually less important consideration is stack padding control / packing, which is intuitively more difficult if you don't declare everything upfront.

See this for more information, although let me emphasize the following paragraph before anyone does anything crazy:

Usually, for the small number of scalar variables in your C programs, bumming out the few bytes you can get by changing the order of declaration won’t save you enough to be significant. The technique becomes more interesting when applied to nonscalar variables - especially structs.

tne
  • 7,071
  • 2
  • 45
  • 68
  • Even though many compilers might arrange the variables on the stack in the order you define them, the C standard does not require them to do so. Some compilers might even do this for you (but I don't know about that). – cmaster - reinstate monica Feb 23 '14 at 16:39
  • @cmaster: That's an excellent point, thanks. For the curious: [1](http://stackoverflow.com/q/4264896), [2](http://stackoverflow.com/q/9535342), [3](http://stackoverflow.com/q/238441), [4](http://stackoverflow.com/q/1850556), [5](http://stackoverflow.com/q/1102049), [6](ftp://gcc.gnu.org/pub/gcc/summit/2003/Optimal%20Stack%20Slot%20Assignment.pdf). I guess my point is moot. – tne Feb 24 '14 at 09:44
0

Now the answer concerning performance.

Should I declare and initialize the local (for the block) data inside the block? Does this have runtime performance cost (due to runtime allocation in the stack)?

Allocation of local variables is practically free. In most cases, it will really be free, because the update of the stack pointer is performed in the same instruction that writes the value to the stack. Deallocation is either free as well (when something is popped off the stack), or done once at the return (when a stack frame had been created).

Or should I declare and/or initialize all variables at function entry, so that is is done in one, possibly faster, operation block?

While allocation is virtually free, running constructors/destructors is not. While this does not apply to variables of primitive types, it applies to virtually all user defined types, including smart pointers and the like. If you declare a smart pointer at the beginning of the function, but only use it half of the time, you construct, and subsequently destruct the smart pointer twice as much as needed.

Also, if you declare a variable where you have the information to initialize it to your needs, you can construct it directly to the state you want it to have instead of first default constructing it only to change it's value afterwards (using the assignment operator in many cases). So, from a performance perspective, you should always declare variables late and only in the blocks that need them.

Or should I seperate the if() blocks in different functions, even though they are only a couple of lines long and used only one in the program?

No, this is completely contraproductive from a performance perspective. Each function call has an overhead, I think it's between 10 and 20 cycles most of the time. You can do quite a bit of calculation in that time.

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106