C ++ многозначный литерал - PullRequest
40 голосов
/ 18 октября 2010

Я не знал, что C и C ++ допускают multicharacter literal: не 'c' (типа int в C и char в C ++), но 'tralivali' (типа int !)

enum
{
    ActionLeft = 'left',
    ActionRight = 'right',
    ActionForward = 'forward',
    ActionBackward = 'backward'
};

Стандарт говорит:

C99 6.4.4.4p10: «Значение целого числасимвольная константа, содержащая более одного символа (например, 'ab'), или содержащая символ или escape-последовательность, которая не отображается на однобайтовый символ выполнения, определяется реализацией. "

Iобнаружили, что они широко используются в C4 двигателя .Но я полагаю, что они небезопасны, когда мы говорим о независимой от платформы сериализации.Это может сбивать с толку и потому, что они выглядят как струны.Итак, какова область применения мультихарактерного литерала, полезны ли они для чего-то?Они в C ++ только для совместимости с кодом C?Они считаются плохой функцией как оператор goto или нет?

Ответы [ 5 ]

28 голосов
/ 18 октября 2010

Упрощает выбор значений в дампе памяти.

Пример:

enum state { waiting, running, stopped };

против

enum state { waiting = 'wait', running = 'run.', stopped = 'stop' };

дамп памяти после следующего оператора:

s = stopped;

может выглядеть так:

00 00 00 02 . . . .

в первом случае, против:

73 74 6F 70 s t o p

с использованием литералов с несколькими символами. (конечно, говорит ли он «стоп» или «поты», зависит от порядка байтов)

18 голосов
/ 18 октября 2010

Я не знаю, насколько широко это используется, но "определение реализации" - это большой красный флаг для меня. Насколько я знаю, это могло бы означать, что реализация могла бы игнорировать ваши обозначения символов и просто назначать нормальные приращения значений, если это необходимо. Это может сделать что-то «более приятное», но вы не можете полагаться на такое поведение в компиляторах (или даже в версиях компиляторов). По крайней мере, "goto" имеет предсказуемое (если нежелательное) поведение ...

Во всяком случае, это мой 2с.

Редактировать: в зависимости от реализации:

С Глоссарий Бьярна Страуструпа C ++ :

определена реализация - аспект Семантика C ++, которая определена для каждая реализация, а не указано в стандарте для каждого реализация. Примером является размер из int (который должен быть не менее 16 биты но могут быть длиннее). избежать поведение, определяемое реализацией когда возможно. Смотрите также: не определено. TC ++ PL C.2.

также ...

undefined - аспект C ++ семантика для которой нет разумных поведение не требуется. Примером является разыменование указателя со значением нуль. Избегайте неопределенного поведения. Увидеть также: реализация определена. TC ++ PL С.2.

Полагаю, это означает, что комментарий правильный: он должен хотя бы компилироваться, хотя ничего кроме этого не указано. Также обратите внимание на совет в определении.

5 голосов
/ 18 октября 2010

Четырехбуквенные литералы, которые я видел и использовал.Они отображаются в 4 байта = одно 32-битное слово.Это очень полезно для целей отладки, как сказано выше.Их можно использовать в операторе switch / case с целочисленными значениями, что неплохо.

Это (4 символа) довольно стандартно (т.е. поддерживается GCC и VC ++ по крайней мере), хотя результаты (фактические значения скомпилированы)варьируются от одной реализации к другой.

Но более 4 символов?Я бы не стал использовать.

ОБНОВЛЕНИЕ: со страницы C4: «Для наших простых действий мы просто предоставим перечисление некоторых значений, что делается в C4 путем указания четырехсимвольных констант».Таким образом, они используют литералы 4 символов, как и в моем случае.

3 голосов
/ 03 января 2016

В C ++ 14 черновик спецификации N4527 раздел 2.13.3, запись 2:

... Обычный символьный литерал, который содержит более одного символа c-char:многозначный буквальный.Литерал с несколькими символами или обычный символьный литерал, содержащий один символ c-char, не представляемый в наборе символов выполнения, поддерживается условно, имеет тип int и имеет значение, определяемое реализацией.

Предыдущийответы на ваш вопрос касались в основном на реальных машинах, поддерживающих литералы с несколькими символами.В частности, на платформах, где int составляет 4 байта, четырехбайтовый мультисимвол хорош и может быть использован для удобства, как в примере с мем-дампом Ферруччо.Но, поскольку нет гарантии, что это когда-нибудь будет работать или работать так же на других платформах, использование литералов с несколькими символами не рекомендуется для переносимых программ .

3 голосов
/ 20 сентября 2015

Литералы с несколькими символами позволяют указывать int значения через эквивалентное представление в символах.Полезно для перечислений, кодов и тегов FourCC, а также параметров шаблонных типов.С литералом, состоящим из нескольких символов, код FourCC может быть введен непосредственно в источник, что очень удобно.

Реализация в gcc описана в https://gcc.gnu.org/onlinedocs/cpp/Implementation-defined-behavior.html.Обратите внимание, что значение усекается до размера типа int, поэтому 'efgh' == 'abcdefgh' если ваши целые имеют ширину 4 символа, хотя gcc выдаст предупреждение о переполнении литерала.

К сожалению, gcc будетвыдает предупреждение для всех многосимвольных литералов, если передано -pedantic, так как их поведение определяется реализацией.Как вы можете видеть выше, возможно, изменится равенство двух многосимвольных литералов при переключении реализаций.

...