Является ли инициализация значения частью стандарта C++98? Если нет, то почему он был добавлен в стандарт C++03?
Ура и hth. - Альф сделал комментарий в этом ответе, что инициализация значения, возможно, является новой особенностью C++03 по сравнению с C++98. Интересно, что он имел в виду.
Является ли инициализация значения частью C++98? Это присутствует в концепции, но не в названии? Почему он был добавлен в стандарт C++03?
У меня есть копия стандарта '03, но нет стандарта '98. Вот определение инициализации по умолчанию и инициализации значения.
По умолчанию инициализировать объект типа T означает:
- если T является типом класса, отличным от POD (раздел 9), вызывается конструктор по умолчанию для T (и инициализация является некорректной, если у T нет доступного конструктора по умолчанию);
- если T является типом массива, каждый элемент инициализируется по умолчанию;
- иначе объект инициализируется нулями.
Инициализировать значение объекта типа T означает:
- если T является типом класса (раздел 9) с конструктором, объявленным пользователем (12.1), то вызывается конструктор по умолчанию для T (и инициализация некорректна, если у T нет доступного конструктора по умолчанию);
- если T является типом класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса в T инициализируются значением;
- если T является типом массива, то каждый элемент инициализируется значением;
- иначе объект инициализируется нулями
Я предполагаю, что '98 имел инициализацию по умолчанию, но не инициализацию значения, и что между ними есть некоторое ключевое различие. Честно говоря, у меня возникают проблемы при разборе стандартного кода здесь, и я не понимаю разницы между определениями.
1 ответ
Цитируя стандартный документ ISO/IEC 14882:1998 (который был изъят из ISO):
По умолчанию инициализировать объект типа
T
средства:
- если T является типом класса не POD (раздел 9), конструктор по умолчанию для
T
называется (и инициализация плохо сформирована, еслиT
не имеет доступного конструктора по умолчанию);- если T является типом массива, каждый элемент инициализируется по умолчанию;
- в противном случае хранилище для объекта инициализируется нулями.
И в пункте 7:
Объект, инициализатором которого является пустой набор скобок, т. Е.
()
, должен быть инициализирован по умолчанию.
Подробная информация об обосновании изменения может быть найдена в отчете о дефектах, который привел к этому:
Это определение подходит для локальных переменных, но не для объектов, которые инициализируются в результате выполнения выражений вида
T()
потому что объекты, полученные с помощью таких выражений, будут скопированы немедленно, и поэтому должны иметь значения, которые гарантированно будут копируемыми.
С этой целью я предлагаю добавить следующий новый текст в пункт 8 статьи 8.5:Инициализировать значение объекта типа
T
средства:
- если T является типом класса (раздел 9 [класс]) с объявленным пользователем конструктором (12.1), то вызывается конструктор по умолчанию для T (и инициализация некорректна, если у T нет доступного конструктора по умолчанию);
- если T является типом класса без объявленного пользователем конструктора, то каждый нестатический член данных и компонент базового класса T инициализируются значением;
- если T является типом массива, то каждый элемент инициализируется значением;
- в противном случае хранилище для объекта инициализируется нулями.
Кроме того, я предлагаю изменить '' default-initialization '' на '' value-initialization '' в 5.2.3 параграфе 2.
И, после этого, историческое объяснение:
Древняя история
Однажды разработчик AT&T по имени Лора Ивс спросила меня: "Какова должна быть ценность
int()
"Сначала я подумал, что это должно быть столько же, сколькоx
после сказанногоint x;
но вскоре я понял, что это определение не подойдет. Причина в том, что x имеет неопределенное значение (при условии, что это локальная переменная), но мы не возражаем, что
x
неопределенна, потому что мы, вероятно, собираемся присвоить значениеx
прежде чем мы используем это. По сравнению,int()
лучше не иметь неопределенное значение, потому что копирование такого значения имеет неопределенный эффект. Было бы глупо запретить компилятору помечатьint()
во время компиляции, только чтобы позволить ему пометить его во время выполнения! [...]