Declaring a static function level variable inside an if block that never gets

My understanding of static variables declared inside a function:

  • If the initial value is not specified, the static variable will be in .bss , otherwise in .data
  • Memory for statics is allocated along with globals - that is, long before execution enters main
    • are these two assumptions correct ?
  • When execution is started for the first time for the first time, the static is initialized by the value specified by the user (or zero if the initial value is not specified).
  • ... and retain their values ​​on subsequent function calls

But what if I declare my static variable inside the if block? I assume that my third point should be updated to "when the execution falls into the line where the static variable is declared, they are initialized ..." - am I right ?

Now, if the if block in which they are declared never hits (and the compiler can figure it out) - I understand that the variable will never be initialized; but is there any memory allocated for this variable?

I wrote two functions to try to figure out what is going on:

 #include <stdio.h> void foo() { static foo_var_out; if(0){ static foo_var_in_0; printf("%d %d\n", foo_var_in_0); } else { static foo_var_in_1; printf("%d %d\n", foo_var_in_1); } } static void bar(int flag) { static bar_var_out; if(flag){ static bar_var_in_0; printf("%d %d\n", bar_var_in_0); } else { static bar_var_in_1; printf("%d %d\n", bar_var_in_1); } } int main() { foo(); bar(0); } 

And I took an object dump:

 $ gcc -o main main.c $ objdump -t main | grep var 45:080495c0 l O .bss 00000004 foo_var_in_1.1779 46:080495c4 l O .bss 00000004 foo_var_out.1777 47:080495c8 l O .bss 00000004 bar_var_in_1.1787 48:080495cc l O .bss 00000004 bar_var_in_0.1786 49:080495d0 l O .bss 00000004 bar_var_out.1785 

From the output, it looks like foo_var_in_0 was not created at all (presumably because it is inside an explicit if(0) ), while bar_var_in_0 was created (how is it possible for the caller to pass a nonzero value value - although the only caller explicitly skips zero).

I assume that my question is: is it right to assume that no memory was allocated for the variable foo_var_in_0 ? I ask about this particular case; Am I reading objdump correctly - or do I need to do something else to check if the variable will occupy some memory during program startup?

In other words, if a line declaring a function-level static variable never hits, is the variable declared at all?

If it will not be created at all, does it comply with the C standard (less likely) or compile time optimization and at what level - how to turn it on or off (in gcc 4.1.1)?

I understand that one int is not a big deal to worry about, but I'm more interested in how this works; also, what if the variable was a large array of size, say, 5000 elements of a 10-byte structure?

+6
c
source share
3 answers

Is it right to assume that no memory was allocated for the variable foo_var_in_0?

No, I don’t think it would be right to assume this. As far as I know, such optimizations are not part of the standard.

If you know that the compiler does this and you want to accept it, continue. If you write everything that is needed for this to happen, you can write a test after assembly to make sure that this happens.

Probably what you see is a side effect of the compiler, which simply cuts off some code that he knew would never work. This means that he is not specifically trying to remove the statics, but he deleted the whole branch, so any code in it just went away.

+3
source share

The C standard does not specify where to place variables and stuff. It simply prescribes that the corresponding implementation should have equivalent behavior (to the reference behavior specified by the standard), where the "equivalent" is also defined by the standard.

So the simple answer is that this is an optimization, and how to enable / disable it depending on the particular compiler.

An implementation that performs interprocedural analysis is also likely to get rid of bar_var_in_0 .

+2
source share

Just add the correct answers from others. Your assumptions about initializing static variables are incorrect.

  • Static storage variables are always initialized. Either explicitly if you provided an initializer or implicitly from 0 .
  • The initializer for such a variable should always be compile time constant expression. Thus, the value computed at compile time and written directly to the object. (Well, if it's all zero, some systems have tricks / special sections that explicitly store the variable in an object file.)
  • So, no, there will be no initializer statement executed when the access variable is the first time (how does the system know the value is another static variable?), But every time you run the program, the variable is already initialized.
+2
source share

All Articles