Почему 3 разных компоновки в объявлении одной переменной не приводят к ошибке?

static auto i{0};

int main() {
  auto i{0};
  { extern int i; }
}

Почему можно трижды объявить одну и ту же переменную с разными компоновками и не получить ошибку? Какая в итоге компоновка будет у переменной?


Ответы (1 шт):

Автор решения: DmitryK

Не знаю о какой компоновке вы говорите. Но у этих переменных разная область видимости, поэтому при объявлении нет ошибки.

static auto i{0}; // глобальная область видимости

int main() 
{
  auto i{0}; // область видимости в пределах функции main()
  {                    // начало блока
     extern int i;     // область видимости в блоке, но переменная из другого блока трансляции
  }                    // конец блока
  for(int i=0; i<10; ++i) // область видимости в блоке, которым является цикл
  {
     if(i<5) // используется переменная, объявленная в цикле
     {}
  }
}

Локальные переменные при использовании имеют приоритет над глобальными. Т.е. при использовании внутри блока, будет использоваться переменная, объявленная в блоке.
Но при использовании всё равно может появиться ошибка - когда компилятор не сможет определить, о какой именно переменной идет речь. При этом, это не самое плохое - хуже когда компилятор сам определился, какую переменную использовать, но это не совпадает с ожиданием программиста. Поэтому лучше не допускать совпадения имен.
А вот так у вас будут проблемы, т.к. область видимости одинаковая и компилятор не сможет выбрать, какую именно из этих переменных использовать.

static auto i{0};
extern int i;

int main() 
{
     if(i<5) // О какой из двух i идет речь?
     {}
}
→ Ссылка