Подтвердить что ты не робот

Не могу понять объявление # 3 в примере [basic.link]/6 С++ 14

[basic.link]/6

Имя функции, объявленной в области блока, и имя переменная, объявленная объявлением блока extern, имеет связь. Если существует объявление visible объекта с привязкой, имеющей одно и то же имя и тип, игнорируя объекты, объявленные вне самой внутренней охватывающая область пространства имен, объявление области блока объявляет, что и получает связь с предыдущей декларацией. Если существует более одного такого совпадающего объекта, программа плохо сформирован. В противном случае, если соответствующий объект не найден, область действия блока объект получает внешнюю связь. [Пример:

static void f();
static int i = 0; // #1
void g() {
    extern void f(); // internal linkage
    int i; // #2 i has no linkage
    {
        extern void f(); // internal linkage
        extern int i; // #3 external linkage
    }
}

В этой программе есть три объекта с именем i. Объект с внутренней связью, введенный декларацией в глобальном масштабе (строка # 1), объект с автоматической продолжительностью хранения и отсутствие связей, введенных декларацией в строке # 2, и объект с статическим временем хранения и внешней связью, введенные декларацией в строке # 3. -end пример]

У меня есть два комментария об этом абзаце:

  • Объявление static int i = 0; в глобальной области видимости не отображается внутри блока, содержащего объявление extern int i; (# 3). Поэтому мы можем только сказать, что это последнее объявление имеет внешнюю связь, т.е. Мы не можем связать его с объявлением № 1.
  • В противном случае, если объявление static int i; считается видимым объявлением № 3, чем в соответствии с текстом в абзаце, объявление области блока объявляет один и тот же объект и получает связь с предыдущей декларацией, то есть внутреннюю связь, а не внешняя связь, как указано в примере.

Что мне здесь не хватает?

4b9b3361

Ответ 1

Это зависит от активной проблемы 426, в которой говорится:

Пример в 3.5 [basic.link], пункт 6, создает две области файлов переменные с тем же именем, с внутренней связью и с внешнее.

static void f();
static int i = 0;                       //1
void g() {
      extern void f();                // internal linkage
      int i;                          //2: i has no linkage
      {
              extern void f();        // internal linkage
              extern int i;           //3: external linkage
      }
}  

Это действительно то, что мы хотим? C99 имеет 6.2.2.7/7, что дает undefinedповедение для отображения идентификатора с внутренним и внешним в одной и той же переводческой единице. С++, похоже, не имеет эквивалентны.

Первоначальное предложение состояло в том, чтобы сделать его undefined:

Мы согласны с тем, что это ошибка. Мы предлагаем оставить этот пример, но измените комментарий, чтобы указать, что строка // 3 имеет поведение undefined, и в другом месте добавляют нормативное правило, дающее такой случай undefinedповедение.

но последние два комментария говорят:

Согласно пункту 3.5 [basic.link] 9, две переменные с связи в предлагаемом примере не являются "одной и той же сущностью", поскольку они не имеют такой же связи. Некоторая другая формулировка будет необходима для описать взаимосвязь между этими двумя переменными.

и

КСР решила, что было бы лучше сделать программу с этим вид несоответствия связи неправильный, а не undefinedповедение.

Последние комментарии не предлагали новую формулировку, и она не обновлялась с 2006 года, поэтому в лучшем случае мы можем сказать, что нынешнее мышление состоит в том, что это плохо сформировано.

Для справки проект стандарта C99 6.2.2.7/7 гласит:

Если в пределах единицы перевода появляется один и тот же идентификатор с внутренним и внешним связь, поведение undefined.