Почему инициализация новой переменной сама по себе действительна?

Рассмотрим некоторый код:

#include  int main() { using std::cout; int a=3; cout << "a="<<a<<"\n"; { int a=a; cout << "new a = " << a << "\n"; a=5; cout << "a = " << a << "\n"; } cout << "old a = " << a << "\n"; } 

Я ожидаю, что он напечатает

 a=3 new a = 3 changed a = 5 old a = 3 

Но то, что я получаю, по-видимому, говорит о new a = 0 во второй строке. Я думал, что это будет работать как список инициализации в конструкторе classа, где можно писать как

 C::C(int a) : a(a) {} 

Но по какой-то причине это другое. Во-первых, полное удаление внешнего кода не приводит к ошибке компиляции. Поэтому я предполагаю, что int a=a; действует. Включение всех предупреждений компилятора приводит к следующему:

 test.cpp: In function 'int main()': test.cpp:10:15: warning: 'a' is used uninitialized in this function int a=a; 

Итак, теперь мой вопрос: почему этот синтаксис действительно действителен? Почему компилятор не говорит что-то вроде «undefined variable a»?

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

 void *p = &p; 

который законно использует имя (но не значение) инициализированной переменной.

Это поведенчески недействительно, так как использование значения неинициализированного объекта дает неопределенное поведение. Это не ошибка, требующая диагноза (так как в целом может быть сложно или невозможно проанализировать stream программы, чтобы увидеть, был ли объект инициализирован), но, как вы заметили, многие компиляторы выдают предупреждение для простых случаев, подобных этому ,

  • Прямые ссылки - почему этот код компилируется?
  • Очень простое определение InitializeComponent (); метод
  • Как инициализировать память новым оператором в C ++?
  • Как я могу инициализировать статическую карту?
  • Как инициализировать var?
  • Инициализация значений и типы не POD
  • Инициализация массива в одной строке
  • Как члены classа C ++ инициализируются, если я не делаю этого явно?
  • слишком много инициализаторов для 'int ' c ++
  • Есть ли разница между инициализацией копирования и прямой инициализацией?
  • Статическая членная переменная C ++ и ее инициализация
  • Давайте будем гением компьютера.