Последнее предложение §6.3.5.1 от Страуструпа Язык программирования C ++ (4-е издание здесь):
Элемент массива или класса инициализируется по умолчанию, если массив или структура.
Тем не мение, этот тест шоу неинициализированным члены инициализированного объекта по умолчанию (я также пытался с g++4.7 -std=c++11
)
#include <iostream>
struct Foo
{
int i;
Foo();
};
Foo::Foo() {}
int main()
{
Foo f;
std::cout << "f.i: " << f.i << std::endl;
return 0;
}
Должно быть, я что-то упускаю, но есть ли объяснение, которое не означает ошибку в утверждении Страуструпа?
РЕДАКТИРОВАТЬ: После ответов я понимаю, что концепция инициализировано по умолчанию должен включать в себя то, что называется неинициализированным в других частях текста (например, в §17.3.1). Это звучит очень непонятно для меня. На самом деле, используя неинициализированным означать что-либо, кроме «явно не инициализированного пользователем» (как в данном случае), противоречие: некоторые вещи по умолчанию инициализированы и еще не инициализированы. Если только не отбросить доказательства естественного языка, что X и un-X классифицируют противоположные, исключительные наборы вещей …
Кроме того, более раннее предложение в том же разделе (§6.3.5.1) гласит:
Локальные переменные […] не инициализируются по умолчанию, если они не имеют пользовательских типов с конструктором по умолчанию […]
Противоречие здесь снова очевидно. Принятие первого и последнего утверждений, чтобы быть правдой подразумевает, что есть переменные (а именно локальные переменные), которые одновременно инициализировано по умолчанию а также по умолчанию не инициализируется.
ИМХО, это в лучшем случае очень нечеткое использование естественного языка для описания чего-либо.
Согласно § 8.5 / 7:
По умолчанию инициализировать объект типа T означает:
— если T является (возможно, cv-квалифицированным) типом класса (раздел 9), вызывается конструктор по умолчанию для T (и инициализация является некорректной, если у T нет доступного конструктора по умолчанию);
— если T является типом массива, каждый элемент инициализируется по умолчанию;
— иначе инициализация не выполняется.
int
попадает в последнюю точку, поэтому он остается неинициализированным. Если ваш член имел тип, скажем, std::string
, это вызвало бы конструктор по умолчанию std::string
и у вас будет пустая строка.
Других решений пока нет …