Рассмотрим компилятор C ++ 11, который имеет набор символов выполнения UTF-8 (и совместим с ABI x86-64, для которого требуется char
введите 8-битный байт со знаком).
Буква Ä (умлаут) имеет кодовую точку Unicode 0xC4
и имеет представление UTF-8 с 2 кодовыми единицами {0xC3, 0x84}
Компилятор назначает символьный литерал '\xC4'
тип int
со значением 0xC4
,
Соответствует ли стандарт компилятора и ABI? Что ты думаешь?
Соответствующие цитаты из стандарта C ++ 11:
2.14.3.1
Обычный символьный литерал, который содержит один символ c-char, имеет тип char, значение которого равно числовому значению кодировки c-char в наборе символов выполнения. Обычный символьный литерал, содержащий более
один символ c-char является многозначным литералом. Литерал с несколькими символами имеет тип int и определяется реализацией
значение.
2.14.3.4
Escape \ xhhh состоит из обратной косой черты, за которой следует x, а затем
одна или несколько шестнадцатеричных цифр, которые используются для указания значения нужного символа. Ценность персонажа
литерал определяется реализацией, если он выходит за пределы определенного реализацией диапазона, определенного для char
§2.14.3 параграф 1, несомненно, является соответствующим текстом в стандарте (C ++ 11). Однако в исходном тексте было несколько дефектов, и последняя версия содержит следующий текст, подчеркнутый:
Буква, состоящая из нескольких символов, или обычный символьный литерал, содержащий один символ c-char, не представимый в наборе символов выполнения, условно поддерживается, имеет тип int, и имеет значение, определяемое реализацией.
Хотя это было принято как дефект, это на самом деле не является частью какого-либо стандарта. Тем не менее, это рекомендация, и я подозреваю, что многие компиляторы это реализуют.
От 2.1.14.3p4:
Значение символьного литерала определяется реализацией, если оно выходит за пределы определенного реализацией диапазона, определенного для
char
Исторически сложилось, что компиляторы x86 (и, как вы указываете, эта практика теперь является официальным стандартом) подписали char
s. \xc7
для этого вне допустимого диапазона, поэтому реализация должна задокументировать буквальное значение, которое она будет производить.
Похоже, что ваша реализация продвигает символьные литералы вне диапазона, указанные с помощью \ x, экранирует целочисленные литералы (в диапазоне).
Вы смешиваете яблоки, апельсины, груши и кумкваты 🙂
Да, «\ xc4» является литералом юридического характера. В частности, то, что стандарт называет «литералом узкого символа».
Из стандарта C ++:
Глифы для членов основного исходного набора символов:
предназначен для идентификации символов из подмножества ИСО / МЭК 10646, который
соответствует набору символов ASCII. Тем не менее, потому что отображение
от символов исходного файла до исходного набора символов (описано в
этап перевода 1) определяется как определенный реализацией,
реализация требуется, чтобы документировать, как основные исходные символы
представлены в исходных файлах.
Это может помочь уточнить:
Это также может помочь, если вы не знакомы с этим:
Вот еще один хороший, краткий и яркий пример: