Ответ 1
Да, это изменение было вызвано изменениями в языке, что делает его неопределенным поведением, если в результате оценки получено неопределенное значение, но с некоторыми исключениями для неподписанных узких символов.
Отчет о дефекте 1787, предлагаемый текст которого можно найти в N3914 1, был недавно принят в 2014 году и включен в последний рабочий проект N3936
:
Наиболее интересное изменение в отношении неопределенных значений было бы в разделе 8.5
параграфа 12, который идет от:
Если для объекта не указан инициализатор, объект инициализируется по умолчанию; если инициализация не выполняется, объект с автоматическим или динамическим сроком хранения имеет неопределенное значение. [Примечание: объекты со статическим или потоковым хранением инициализируются нулями, см. 3.6.2. - конец примечания]
чтобы (выделение мое):
Если для объекта не указан инициализатор, объект инициализируется по умолчанию. При получении хранилища для объекта с автоматическим или динамическим сроком хранения объект имеет неопределенное значение, и если для объекта не выполняется инициализация, этот объект сохраняет неопределенное значение до тех пор, пока это значение не будет заменено (5.17 [expr.ass]), [Примечание: объекты со статическим или потоковым хранилищем инициализируются нулями, см. 3.6.2 [basic.start.init]. - примечание] Если в результате оценки получено неопределенное значение, поведение не определено, за исключением следующих случаев:
Если неопределенное значение беззнакового типа узкого символа (3.9.1 [basic.fundamental]) получается путем оценки:
второй или третий операнд условного выражения (5.16 [expr.cond]),
правый операнд запятой (5.18 [expr.comma]),
операнд приведения или преобразования в беззнаковый узкий символьный тип (4.7 [conv.integral], 5.2.3 [expr.type.conv], 5.2.9 [expr.static.cast], 5.4 [expr.cast]), или же
выражение отброшенного значения (раздел 5 [expr]),
тогда результат операции является неопределенным значением.
Если неопределенное значение типа узких символов без знака (3.9.1 [basic.fundamental]) создается путем вычисления правого операнда простого оператора присваивания (5.17 [expr.ass]), первый операнд которого является lvalue узкого знака без знака тип символа, неопределенное значение заменяет значение объекта, на которое ссылается левый операнд.
Если неопределенное значение узкого символьного типа без знака (3.9.1 [basic.fundamental]) создается путем вычисления выражения инициализации при инициализации объекта узкого символьного типа без знака, этот объект инициализируется неопределенным значением.
и включил следующий пример:
[ Пример:
int f(bool b) { unsigned char c; unsigned char d = c; // OK, d has an indeterminate value int e = d; // undefined behavior return b ? d : 0; // undefined behavior if b is true }
- конец примера]
Мы можем найти этот текст в N3936, который является текущим рабочим проектом, а N3937
- C++14 DIS
.
До C++ 1 год
Интересно отметить, что до этого проекта в отличие от C, который всегда имел четко определенное представление о том, какие использования неопределенных значений были неопределенными C++ использовал термин неопределенное значение, даже не определяя его (предполагая, что мы не можем заимствовать определение из C99) а также см. отчет о дефекте 616. Мы должны были полагаться на недостаточно конкретное преобразование lvalue-в-значение, которое в проекте стандарта C++ 11 описано в разделе 4.1
в пункте 1 преобразования Lvalue-в-значение, в котором говорится:
[...] если объект не инициализирован, программа, которая требует этого преобразования, имеет неопределенное поведение. [...]
Примечания:
-
1787
- это версия отчета о дефекте 616, эту информацию можно найти в N3903