Мое понимание статических переменных, объявленных внутри функции:
- Если начальное значение не указано, статическая переменная будет находиться в
.bss
, в противном случае в .data
- Память для статики выделяется вместе с глобальными переменными, т. Е. Задолго до того, как исполнение входит в
main
- правильны ли эти два предположения ?
- Когда выполнение попадает в функцию в первый раз, статика инициализируется указанным пользователем значением (или нулем, если начальное значение не указано).
- ... и они сохраняют свои значения при последующих вызовах функции
Но что, если я объявлю свою статическую переменную внутри блока if
? Я предполагаю, что мой третий пункт должен быть обновлен до "когда выполнение достигает строки, где объявлена статическая переменная, они инициализируются в ..." - я прав ?
Теперь, что если блок if
, в котором они объявлены, никогда не попадет (и компилятор сможет это выяснить) - я понимаю, что переменная никогда не будет инициализирована; но выделяется ли память для этой переменной?
Я написал две функции, чтобы попытаться выяснить, что происходит:
#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);
}
И я взял дамп объекта:
$ 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
Из выходных данных это выглядит так, как будто foo_var_in_0
вообще не было создано (предположительно потому, что оно находится внутри явного if(0)
), тогда как bar_var_in_0
было создано (поскольку для вызывающей стороны возможно передать ненулевое значение значение - хотя единственный вызывающий явно передает ноль).
Наверное, мой вопрос: правильно ли считать, что для переменной foo_var_in_0
вообще не было выделено памяти? Я спрашиваю об этом конкретном случае; я правильно читаю objdump - или я должен сделать что-то еще, чтобы проверить, займет ли переменная некоторую память во время работы программы?
Другими словами, если строка, которая объявляет статическую переменную уровня функции, никогда не удаляется, действительно ли эта переменная объявлена вообще?
Если он вообще не будет создан, это по стандарту C (менее вероятно) или по оптимизации времени компиляции и на каком уровне - как включить / выключить его (в gcc 4.1.1)?
Я понимаю, что один int - не большое дело, но меня больше интересует, как он работает; Кроме того, что, если переменная была большого массива размера, скажем, 5000 элементов 10-байтовой структуры?