views:

314

answers:

5

I have a question about the following C code:

void my_function()
{
    int i1;
    int j1;

    // Do something...

    if (check_something())
    {
        int i2;
        int j2;

        // Do something else...
    }

    // Do some more stuff...
}

Are there any guarantees about when stack space is allocated/deallocated for i2 and j2 or does it depend on the compiler? I would expect the stack pointer to be adjusted down when i2 and j2 come into scope and adjusted back up when they go out of scope, but then thought some compilers may just "optimize" the whole thing and account for variables in a nested scope when the function is first entered.

I know I can look at the assembly code generated by my compiler, but was wondering if the implementation can be left up to the compiler.

Thanks!

+6  A: 

There are no guarantees.

Different optimization flags will likely result in different methods of saving variables.

The compiler can even make 1 or more variables not use the stack at all and keep them in registers for the whole duration of the function execution.

pmg
+! for no guarantees.
Ben S
+3  A: 

As I understand you even can't receive any guarantee these variables are allocated on stack, they could be stored in registers.

What you really could affect here:

  • Advice compiler to place variable to register by using register keyword.

  • Help compiler with localizing variable scope by moving declaration to as late place as you can:

    int f(void )  
    {
        /* var1 and var2 probably use the same place for storage. */
        {
             int var1;
             /* ... do something */
        }

        {
             int var2;
             /* ... do something */
        }
    }


  • Even given defined scope delay initialization:
{
   int i; /* Yes, you must declare it at the begin of block.

   /* Do something... */

   i = START_VALUE;
   /* But you need it only here and below... */
}
Roman Nikitchenko
+4  A: 

The compiler is free to do whatever it wants, as long as the semantics of the language are reserved. In other words, i2 and j2 can be bound to memory places before the execution reaches the entry point of their block, and can be unbounded any time as long as that doesn't affect the semantics of your code.

AraK
A: 

if "check_something()" is easily evaluated to 0, that whole block will be optimized out using a sufficiently high level of optimization. Yes, it's compiler-dependent. Generally, if you're checking the return value of a function call, it won't be optimized out. The best way to approach this would be to compiler it and actually look at the disassembly of the file to verify what you think is happening is actually happening.

Jeff Lamb
+1  A: 

If the variables are going to be put on the stack, the stack space is allocated at the beginning of the function before the first statement in the function. The stack pointer will be moved up (or down) the total number of bytes to store all the local variables.

Robert