Можно ли объявить несколько статических переменных с одним и тем же именем в одном файле C? - PullRequest
10 голосов
/ 28 мая 2010

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

Ответы [ 6 ]

18 голосов
/ 28 мая 2010

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

6 голосов
/ 28 мая 2010

Существует разница между видимостью и экстентом ; Кроме того, ключевое слово static имеет различные значения в зависимости от области видимости.

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

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

2 голосов
/ 28 мая 2010

Блок видимости. Читай К & Р

2 голосов
/ 28 мая 2010

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

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

1 голос
/ 28 мая 2010

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

0 голосов
/ 27 сентября 2017

Обе функции будут создавать разные стеки, поэтому статическая часть также будет отличаться . Поэтому это возможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...