Действительно ли возможно объявить несколько статических переменных того же имени в единственном файле C с различными объемами? Я записал простую программу для проверки этого, и в gcc она была скомпилирована и хорошо работала.
Код:
static int sVar = 44;
void myPrint2()
{
printf("sVar = %d\n", sVar++);
}
void myPrint()
{
static int sVar =88;
printf("sVar = %d\n", sVar++);
}
int main(void)
{
static int sVar = 55;
int i = 0;
for (i = 0; i < 5; i++)
myPrint();
printf("sVar = %d\n", sVar);
myPrint2();
return(0);
}
Теперь мой вопрос, так как вся "статическая" переменная будет находиться в том же разделе (.data) затем, как у нас может быть несколько переменных с тем же именем в одном разделе?
Я использовал objdump
проверять другой раздел и нашло что все статические переменные (sVar
) были в разделе .data, но с различными именами:
0804960c l O .data 00000004 sVar
08049610 l O .data 00000004 sVar.1785
08049614 l O .data 00000004 sVar.1792
То, почему компилятор, меняет имя переменных (так как C не поддерживает искажение имени)?
Локальная статическая переменная функции отличается от глобальной статической переменной .
Поскольку может быть столько статик, локальных для функции, с одним и тем же именем, сколько вам нужно (при условии, что все они находятся в разных областях), компилятору, возможно, придется изменить их имена внутри (включая имя функции или номер строки или что-то еще), поэтому что компоновщик может отличить их друг от друга.
Существует разница между visibility и extent; также ключевое слово static
имеет различные значения в зависимости от области видимости.
Добавление ключевого слова static
к блочным версиям sVar
(myPrint::sVar и main::sVar) изменяет их extent (время жизни), но не их видимость; обе они видны только в пределах своих соответствующих функций и будут затенять или скрывать файловую версию в своей локальной области видимости. Это указывает на то, что переменные имеют статическую протяженность, то есть память для них выделяется при запуске программы и хранится до ее завершения (в отличие от автоматической или локальной протяженности, где время их жизни ограничено областью, в которой они определены).
Добавление ключевого слова static
к версии sVar
для области видимости файла не изменяет ее размер (переменные области видимости файла имеют статический размер по определению), но изменяет ее видимость относительно других единиц трансляции; имя не экспортируется компоновщику, поэтому к ней нельзя получить доступ по имени из другой единицы трансляции. Оно остается видимым в пределах текущей единицы трансляции, поэтому myPrint2 может получить к нему доступ.
Ключевое слово static имеет разные значения, когда оно глобальное и локальное, первое sVar
- это просто глобальная переменная, недоступная для других блоков трансляции. А статические переменные sVar
в myPrint()
и main()
находятся в разных диапазонах, поэтому это разные переменные. В теле myPrint()
sVar
относится к локальной статической (скрывая глобальную sVar
), в myPrint2()
она относится к глобальной (она не скрыта ничем локальным), а в main()
ссылается на локальный static sVar
, который снова скрывает глобальный с момента его объявления.
Ваша первая sVar
является глобальной для файла, вторая - локальной для функции myPrint()
и третья - локальной для main()
Статические переменные уровня функции недоступны за пределами функции - они просто сохраняют свои значения при последующих вызовах. Я предполагаю, что вы уже заметили это при выполнении вашего кода.