Ответ 1
Онлайн-ссылки, такие как cppreference.com, хороши вплоть до точки. Но известно, что иногда иногда случаются ошибки или неверные интерпретации. Поэтому, имея дело с такими странностями, всегда хорошо идти на официальный стандарт С++.
N3936
§8.5 Инициализаторы [dcl.init]
12 [...] При хранении для объекта с автоматическим или динамическим хранилищем длительность, объект имеет неопределенное значение, и если для объекта не выполняется инициализация, этот объект сохраняет неопределенное значение до тех пор, пока это значение не будет заменено (5.17). [...] Если неопределенное значение получается путем оценки, поведение undefined за исключением следующих случаев:
Если неопределенное значение беззнакового типа узкого символа (3.9.1) получается путем оценки
[...]
операнд приведения или преобразование в неподписанный тип узкого символа (4.7, 5.2.3, 5.2.9, 5.4)
[...]
то результатом операции является неопределенное значение.
Если неопределенное значение типа беззнакового узкого символа создается путем вычисления правильного операнда простого присваивания оператор (5.17), первым операндом которого является lзначение беззнакового узкого тип символа, неопределенное значение заменяет значение объект, на который ссылается левый операнд
Если неопределенное значение беззнакового узкого символьного типа создается путем оценки выражения инициализации, когда инициализация объекта беззнакового узкого символьного типа, этот объект инициализируется неопределенным значением.
Пример:
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 }
Итак (к моему большому удивлению) стандарт поддерживает это.
Что касается причин, то наиболее вероятная причина также может быть найдена в стандарте:
§3.9.1 Основные типы [basic.fundamental]
1 [...] Для неподписанных типов узких символов все возможные битовые шаблоны представления значений представляют числа. Эти требования не выполняются для других типов
Как побочная заметка, я просто понял, что это может использовать злой интервьюер:
Q. Можете ли вы в четко определенном поведении изменить действительное значение объекта на неопределенное значение? Если да, то как?
а.
unsigned char ind;
unsigned char x = 24;
x = ind; // x had a valid value, now x has an indetermined value