Когда будет фундаментальный тип C ++, такой как int
или же float
, есть неизвестное начальное значение?
Как влияет тип распределения памяти, если вообще? Как насчет декларации? Что делать, если это член class
/struct
/union
? Отличается ли C ++ 11 от C ++ 03 или C ++ 98?
У меня есть подозрения, но я не знаю, является ли мои знания полными (или правильными, если на то пошло)
любой POD Данные (включая все основные типы) будут иметь неизвестное значение, когда оба:
new
)Глобальные / статические переменные всех типов устанавливаются в ноль как часть процесса запуска до main
называется. Конструкторы вызываются для типов, которые имеют конструкторы до main
1.
Все, что не инициализировано в конструкторе, также неизвестно.
Редактировать: уточнить, std::string
хороший пример «конструктор не инициализирует все» — если у вас есть локальный std::string str;
, затем str
будет иметь определенное содержимое «пустой строки», но содержимое фактического буфера или даже того, на что указывает буфер, может вообще не иметь ничего значащего — поскольку реализация может определяться на основе длины [или каким-либо другим способом] есть ли доступный буфер или нет, как только мы начнем использовать строку для хранения вещей].
Edit2: Как поясняется в комментарии, вы также можете иметь «гибридные» случаи, когда части структуры инициализируются, например, struct
который содержит некоторые элементы «простых данных» и некоторые элементы, которые имеют конструкторы. У тех, у кого есть конструкторы, будет назван их конструктор. Простые данные не будут инициализированы.
1 Вполне может быть, что код, выполняющий конструкторы, является частью или вызывается изнутри «основной» функции — но если это так, то это произойдет «до того, как какой-либо ваш код в main будет запущен».
Из «Рабочего проекта C ++, 2012-11-02»
3.6.2 Инициализация нелокальных переменных [basic.start.init]
2 Переменные со статической продолжительностью хранения (3.7.1) или продолжительностью хранения потока (3.7.2) должны быть инициализированы нулями (8.5)
до любой другой инициализации.
Переменные со статическим хранилищем по крайней мере ноль инициализирован.
3.7.3 Автоматическая продолжительность хранения [basic.stc.auto]
2 [Примечание: эти переменные инициализируются и уничтожаются, как описано в 6.7. — конец примечания]
6.7 ничего не говорит о как автоматические переменные инициализируются.
3.7.4. Динамическая продолжительность хранения [basic.stc.dynamic]
…
3.7.4.1 Функции размещения [basic.stc.dynamic.allocation]
… При возврате из
функция распределения. Порядок, смежность и Начальное значение памяти, выделенной последовательными вызовами к
функция распределения не определены.8.5 Инициализаторы [dcl.init]
7 По умолчанию инициализировать объект типа T означает:
— если T является (возможно, cv-квалифицированным) типом класса (раздел 9), вызывается конструктор по умолчанию для T (и
инициализация некорректна, если у T нет доступного конструктора по умолчанию);
— если T является типом массива, каждый элемент инициализируется по умолчанию;
— иначе инициализация не выполняется.
Если вы предоставите явный инициализатор, любая переменная будет иметь известное значение.
Если вы не предоставите явный инициализатор для типа POD, это зависит от класса хранилища. Статические или потоковые переменные будут инициализироваться нулями, тогда как автоматические или динамически назначаемые переменные не будут.
Если у вас составной тип, применяются те же правила. Если у вас нет явного инициализатора, с помощью конструктора (по умолчанию) или иным образом, начальное значение основных типов зависит от класса хранилища.
Наконец, память выделяется через malloc
будет неинициализирован, тогда как calloc
память будет нулевой инициализирована.