Разное поведение компиляторов с внешней связью - PullRequest
2 голосов
/ 27 ноября 2011

Когда я компилирую следующие источники в VC ++ 10, i со статической связью присваивается 42 Но в G ++ 4.5.1, i с внешней связью в source2.cpp присваивается 42.

Любые идеи о том, каким должен быть стандарт, подтверждающий поведение в соответствии со Стандартом или почему?

// source1.cpp

#include <iostream>

static int i = 0;

int h();
void foo()
{
     int i;
     {
         extern int i;
         i = 42;
     }
}

int main()
{
    foo();

    std::cout << i << std::endl;
    std::cout << h() << std::endl;
}

// source2.cpp

int i;
int h() { return i; }

1 Ответ

2 голосов
/ 27 ноября 2011

ИСО / МЭК 14882: 2011 3.5 / 6:

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

Внутри внутреннего блока в foo(), объявление int i; скрывает объявление в глобальной области пространства имен: static int i;, поэтому нет видимого i со связью внутри внутреннего блока. Это означает, что extern int i; относится к объекту с внешней связью в пространстве имен, сразу включающему foo().

Назначение должно влиять на i с внешней связью (определенной в source2.cpp), оно не должно влиять на i с внутренней связью, определенной в source1.cpp.

...