Почему компилятор не выдает ошибку, когда возвращается неинициализированная переменная?

#include <iostream>

using namespace std;

int weirdVariable = weirdVariable  + 1;
int main() {
  cout<< weirdVariable ;
  return weirdVariable ;
}

Мне просто интересно, как эта неинициализированная переменная не возвращает ошибку и не возвращает 1. Так что мой вопрос, как / почему она возвращает значение "1". Эта программа логически верна? Или это какой-то недостаток?

2 ответа

Решение

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

§3.6.2 [basic.start.init] Переменные со статической продолжительностью хранения (3.7.1) или продолжительностью хранения потока (3.7.2) должны быть инициализированы нулями (8.5), прежде чем произойдет любая другая инициализация.

Если бы вы должны были объявить wierdVariable как местный mainбыло бы неинициализировано. Это даст вам неопределенное поведение, потому что выполнение преобразования lvalue в rvalue (читай: используя значение) для неинициализированного объекта дает неопределенное поведение.

§4.1 [conv.lval] Если объект, на который ссылается glvalue, не [...] неинициализирован, программа, для которой требуется это преобразование, имеет неопределенное поведение.

Статические и глобальные переменные по умолчанию инициализируются в 0, так что это совершенно нормально

Стандарт C ISO / IEC 9899: 1999 aka C99 (и C++) говорит, что так и должно быть. См. Пункт 10 в разделе 6.7.8 ("Инициализация") WG14 N1256 для точного текста ( /questions/8121741/gcc-avtomaticheski-initsializiruet-staticheskie-peremennyie-v-nol/8121747#8121747)

Кстати: хорошая практика - инициализировать статические переменные, а также просто сделать код более читабельным!

static int myvar = 0;

Еще один недостаток - не инициализировать их: если компилятор не следует стандарту, у вас могут возникнуть проблемы

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

Другие вопросы по тегам