Действительно ли возможно объявить несколько статических переменных с тем же именем в единственном файле C?

Действительно ли возможно объявить несколько статических переменных того же имени в единственном файле 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 не поддерживает искажение имени)?

10
задан Jonathan Leffler 13 April 2014 в 04:14
поделиться

5 ответов

Локальная статическая переменная функции отличается от глобальной статической переменной .
Поскольку может быть столько статик, локальных для функции, с одним и тем же именем, сколько вам нужно (при условии, что все они находятся в разных областях), компилятору, возможно, придется изменить их имена внутри (включая имя функции или номер строки или что-то еще), поэтому что компоновщик может отличить их друг от друга.

20
ответ дан 3 December 2019 в 14:52
поделиться

Существует разница между visibility и extent; также ключевое слово static имеет различные значения в зависимости от области видимости.

Добавление ключевого слова static к блочным версиям sVar (myPrint::sVar и main::sVar) изменяет их extent (время жизни), но не их видимость; обе они видны только в пределах своих соответствующих функций и будут затенять или скрывать файловую версию в своей локальной области видимости. Это указывает на то, что переменные имеют статическую протяженность, то есть память для них выделяется при запуске программы и хранится до ее завершения (в отличие от автоматической или локальной протяженности, где время их жизни ограничено областью, в которой они определены).

Добавление ключевого слова static к версии sVar для области видимости файла не изменяет ее размер (переменные области видимости файла имеют статический размер по определению), но изменяет ее видимость относительно других единиц трансляции; имя не экспортируется компоновщику, поэтому к ней нельзя получить доступ по имени из другой единицы трансляции. Оно остается видимым в пределах текущей единицы трансляции, поэтому myPrint2 может получить к нему доступ.

6
ответ дан 3 December 2019 в 14:52
поделиться

Ключевое слово static имеет разные значения, когда оно глобальное и локальное, первое sVar - это просто глобальная переменная, недоступная для других блоков трансляции. А статические переменные sVar в myPrint() и main() находятся в разных диапазонах, поэтому это разные переменные. В теле myPrint() sVar относится к локальной статической (скрывая глобальную sVar), в myPrint2() она относится к глобальной (она не скрыта ничем локальным), а в main() ссылается на локальный static sVar, который снова скрывает глобальный с момента его объявления.

1
ответ дан 3 December 2019 в 14:52
поделиться

Блокирование блоков. Прочитайте K & R.

2
ответ дан 3 December 2019 в 14:52
поделиться

Ваша первая sVar является глобальной для файла, вторая - локальной для функции myPrint() и третья - локальной для main()

Статические переменные уровня функции недоступны за пределами функции - они просто сохраняют свои значения при последующих вызовах. Я предполагаю, что вы уже заметили это при выполнении вашего кода.

2
ответ дан 3 December 2019 в 14:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: