Нет привязки к блоку?

У всех переменных, объявленных в блоке, нет ссылки?

Например:

1

Если я объявляю статическую переменную:

void foo()
{
   static int i;
}

Будет ли у него внутренняя связь или нет связи? Если нет связи, то зачем статично?

2

Что произойдет, если я использую extern?

/*global scope*/
static int i;

void foo()
{
    extern int i;
}

В этом случае, какая будет связь i?

Ответ 1

Действительно, "нет связи" в области функций.

Цель - управление жизненным циклом: статичность имеет время жизни глобального статического элемента, в то время как она имеет видимость (область видимости) локального.

Примечание

В С++ вы также можете объявить статику ( "глобальные" ) без привязки, заключая их в анонимное пространство имен. Этот трюк обычно используется в библиотеках только для заголовков:

namespace /*anon*/
{
    void foo() {}    // only in this translation unit
    int answer = 42; // this too
}

Что произойдет, если я использую extern?

Если вы используете extern, объявление является только объявлением extern (ничего не определено). Как таковой, обычно можно ожидать, что внешняя связь по определению будет определена в другой единицы перевода. (Таким образом, он действует так же, как если бы он был объявлен в глобальном масштабе). Это похоже на объявления локальных функций:

int main()
{
    void exit(int); // equivalent to non-local declaration
}

Обратите внимание, что в примере 2. переменная i уже была объявлена ​​static, и поэтому она не получит внешнюю привязку. Однако я мог бы быть объявлен в другой единицы перевода без конфликтов компоновщиков.

Ответ 2

  • "Будет ли у него внутренняя связь или нет связи? Если нет связи, то зачем статично?" - у него не было бы никакой связи. static указывает продолжительность статического хранения.

  • "Что произойдет, если я использую extern?" Это будет объявление имени с внешней связью, и поскольку в глобальной области нет ни одного, программа сообщит об ошибках связи. Изменить:. Поскольку в области видимости указано предыдущее объявление static, стандарт говорит, что имя "получает ссылку предыдущей декларации" 3.5/6, поэтому i внутри foo() будет иметь внутреннюю связь.