Нет связи в области блока?

Все ли переменные, объявленные в блоке, не имеют связи?

Например:

1:

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

void foo()
{
   static int i;
}

Будет ли это иметь внутреннюю связь или не будет связи? Если нет связи, то зачем делать ее статической?

2:

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

/*global scope*/
static int i;

void foo()
{
    extern int i;
}

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


person user103214    schedule 23.11.2011    source источник


Ответы (2)


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

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

Примечание

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

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 и поэтому не получит внешней связи. Однако я могу быть объявлен в другой единице перевода без конфликтов компоновщика.

person sehe    schedule 23.11.2011
comment
Таким образом, он имеет внешнюю связь по определению. Самое смешное, что extern не означает автоматически внешнюю связь. Это означает, что у имени есть связь, но она может быть внутренней, как в исходном примере. - person Gene Bushuyev; 23.11.2011
comment
@sehe -- #2, где используется extern, фактически определяет имя с внутренней связью. - person Gene Bushuyev; 23.11.2011
comment
@GeneBushuyev: да, я немного запутался. Обновил мой ответ. Спасибо - person sehe; 23.11.2011

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

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

person Gene Bushuyev    schedule 23.11.2011
comment
Вы имеете в виду, что его второй фрагмент кода будет содержать ошибки ссылок? Это сработало для меня - person Michael Mrozek; 23.11.2011
comment
@Michael Mrozek - у меня все работало нормально, это никогда не ответ. Важно то, что говорит стандарт. Должен сказать, что пропустил предыдущий static, поэтому редактирую свой ответ. - person Gene Bushuyev; 23.11.2011