Нет связи в области блока? - PullRequest
10 голосов
/ 23 ноября 2011

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

Например:

1:

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

void foo()
{
   static int i;
}

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

2:

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

/*global scope*/
static int i;

void foo()
{
    extern int i;
}

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

Ответы [ 2 ]

6 голосов
/ 23 ноября 2011

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

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

Примечание

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

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

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

...