Почему локальная переменная инициализируется по умолчанию?

В разделе 9.2 книги "Язык программирования C++" Бьярн Страуструп писал:

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

Но следующая программа печатает значение 0:

#include <iostream>
using namespace std;

int main() {
    int x;
    cout << x << endl;
    return 0;
}

Разве это не должно возвращать какую-то ошибку?

я использую g++ Скомпилировать.

3 ответа

Решение

Но следующая программа печатает значение 0 на моем терминале.

Он имеет неопределенное поведение, потому что cout строка пытается прочитать из неинициализированного int, Любой вывод, который вы видите, и фактически любое поведение вообще не гарантируется.

Разве это не должно возвращать какую-то ошибку?

Нет, это не так, как работает неопределенное поведение. Вы можете увидеть или не увидеть ошибку.

xнеинициализирован, поэтому ваш фрагмент на самом деле имеет неопределенное поведение.


Разве это не должно возвращать какую-то ошибку?

g++не предупреждает о неинициализированных значениях по умолчанию.

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

g++ -Wuninitialized your_file.c

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

Больше информации о вариантах предупреждения здесь

Разве это не должно возвращать какую-то ошибку?

Нет, не должно, но эта ошибка обнаруживается Valgrind:

$ valgrind --track-origins=yes ./a.out
==4950== Memcheck, a memory error detector
==4950== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4950== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4950== Command: ./a.out
==4950== 
==4950== Conditional jump or move depends on uninitialised value(s)
==4950==    at 0x4F4444A: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:874)
==4950==    by 0x4F504C4: put (locale_facets.h:2371)
==4950==    by 0x4F504C4: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73)
==4950==    by 0x40076D: main (t.cpp:5)
==4950==  Uninitialised value was created by a stack allocation
==4950==    at 0x400757: main (t.cpp:3)
==4950== 

Эта часть результатов Valgrind четко гласит, что:

==4950==  Uninitialised value was created by a stack allocation
==4950==    at 0x400757: main (t.cpp:3)
==4950== 
Другие вопросы по тегам