Конструктор — Сохраняет ли инициализация по умолчанию в C ++ предшествующую инициализацию нуля?

Если конструктор C ++ для объекта со статической продолжительностью хранения не инициализирует элемент, требуется ли это для сохранения предыдущей инициализации нуля или он оставляет элемент с неопределенным значением?

Мое чтение спецификации C ++ заключается в том, что она противоречит сама себе.

Пример:

#include <iostream>

struct Foo { Foo(); int x; } object;

Foo::Foo() { }

int main() { std::cout << object.x << std::endl; }

Конструктор Foo () явно не инициализирует член object.x, поэтому
согласно примечанию в пункте 12.6.2:

член имеет неопределенную ценность.

Но работая с деталями различных инициализаций, это, кажется,
быть неверным. Член object.x инициализируется нулями, так как он имеет static-storage-duration, и тогда я не вижу ничего, что это меняет.

Что касается конструктора, то применяется текст в 12.6.2:

объект инициализируется по умолчанию.

В п. 7 8.5 соответствующий случай инициализации по умолчанию:

… инициализация не выполняется

что я прочитал, чтобы означать, что предыдущая инициализация нуля не изменяется при инициализации по умолчанию.

Я пропускаю какой-то другой текст, который сбрасывает все члены в «неопределенное значение» в начале вызова конструктора?

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

В этом случае, вероятно, нет практического эффекта. Но в более сложном конструкторе, когда некоторые члены инициализированы, а другие нет, должен ли компилятор точно отслеживать, какие байты / биты инициализированы? Или он может просто инициализировать весь объект (например, упростив конструктор до вызова memset () )?

8

Решение

Отчет о дефекте 1787 привести к изменению, задокументированному в N3914 являющийся применяется к проекту стандарта для C ++ 14. Какие изменения [dcl.init] параграф 12 из:

Если для объекта не указан инициализатор, объект
по умолчанию инициализируется; если инициализация не выполняется, объект с
длительность автоматического или динамического хранения имеет неопределенное значение. [ Заметка:
Объекты со статическим или потоковым хранением инициализируются нулями,
см. 3.6.2. — конец примечания]

чтобы:

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

(5.17 [expr.ass]). [Примечание: объекты со статическим или потоковым хранилищем
длительность инициализируется нулями, см. 3.6.2 [basic.start.init]. -конец
примечание] Если в результате оценки получено неопределенное значение,
поведение не определено, за исключением следующих случаев:

[…]

Это проясняет ситуацию неопределенного значения только для объектов автоматической или динамической длительности хранения. Поскольку это было применено в отчете о дефектах, оно, вероятно, также применимо к C ++ 11, так как отчет о дефектах возник до того, как был принят C ++ 14, но он также может применяться и в дальнейшем. Правила того, как далеко должен применяться дефект, никогда не были мне ясны.

Поскольку в комментариях было упомянуто место размещения, изменилось то же изменение. [Expr.new], сделав часть с неопределенным значением комментарием:

Если новый инициализатор опущен, объект инициализируется по умолчанию
(8.5 [dcl.init]); если. [Примечание: если инициализация не выполняется,
Объект имеет неопределенное значение. —Конечная записка]

В начале раздела говорится:

[…] Объекты, созданные новым выражением, имеют динамическое хранилище
продолжительность (3.7.4). […]

Которые кажутся достаточными, чтобы применить изменения в разделе [Dcl.init].

Это изменение было также интересно, так как до этого изменения термин неопределенное значение не было определено в стандарте C ++.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]