Ответ 1
ЭТО МОЖЕТ УДОВЛЕТВОРИТЬ,
но нет такой гарантии в стандарте С++ 11 (N3337), ни в предстоящем С++ 14 (N3797).
char unsigned * p1 = ...;
char * p2 = reinterpret_cast<char *> (p1);
*p1 == *p2; // (1), not guaranteed to be true
Примечание. Это конкретная реализация, независимо от того, подписан ли char
или без знака; [basic.fundamental]p1
.
ПОДРОБНОСТИ
Стандарт гарантирует, что каждый тип символа должен быть
- имеют одинаковое требование выравнивания;
- занимают одинаковое количество хранилища и
- что все биты хранилища, занятые символьным типом, должны участвовать в представлении значений и;
- что представление значения одинаков.
Обмен тем же объемом хранения, требованиями к выравниванию и гарантией участия в бит означает, что листинг lvalue, относящийся к одному типу (без знака char), другому (char), является безопасным.. насколько это возможно как фактическое литье.
3.9.1p1
Основные типы[basic.fundamental]
Определяется реализацией, может ли
char
сохранять отрицательные значения. Символы могут быть явно объявленыsigned
илиunsigned
.A
char,
asigned char,
и aunsigned char
занимают одинаковое количество хранения и имеют одинаковые требования к выравниванию (3.11); то есть они имеют одно и то же представление объекта. Для типов символов в представлении значений участвуют все биты представления объекта.Для неподписанных типов символов все возможные битовые шаблоны представления значений представляют числа. Эти требования не подходят для других типов.
3.9p4
Типы[basic.types]
Объектное представление объекта типа
T
представляет собой последовательность объектов Nunsigned char
, занятых объектом типаT,
, гдеN
равноsizeof(T)
. Представление значения объекта - это набор битов, которые содержат значение типаT
.
SO, ЧТО ПРОБЛЕМА?
Если мы назначим максимальное значение unsigned char (UCHAR_MAX) на *p1
и *p2
, *p2
не будет способный представлять это значение. Мы переполним *p2
и, скорее всего, получим значение -1
.
Примечание: целочисленное переполнение цепочки - это фактически поведение undefined.
*p1 = UCHAR_MAX;
*p1 == *p2; // (1)
Обе стороны operator==
должны иметь один и тот же тип, прежде чем мы сможем их сравнить, и в настоящее время одна сторона unsigned char
, а другая char
.
Компилятор должен использовать интегральную рекламу, чтобы найти тип, который может представлять все комбинированные возможные значения двух типов; и в этом случае результирующий тип будет int
.
После цельной акции утверждение семантически эквивалентно int (UCHAR_MAX) == int(-1)
, что, конечно, ложно.