С++ многоканальный литерал

Я не знал, что C и С++ позволяют multicharacter literal: not 'c' (типа int в C и char в С++), но "tralivali" (типа int!)

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

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

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

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

Ответ 1

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

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

Изменить: "Определено для реализации":

Из Bjarne Stroustrup С++ Глоссарий:

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

и...

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

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

Ответ 2

Это облегчает выбор значений в дампе памяти.

Пример:

enum state { waiting, running, stopped };

против.

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

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

s = stopped;

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

00 00 00 02 . . . .

в первом случае vs:

73 74 6F 70 s t o p

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

Ответ 3

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

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

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

UPDATE: со страницы C4: "Для наших простых действий мы просто предоставим перечисление некоторых значений, которые выполняются на C4, указав четырехсимвольные константы". Таким образом, они используют 4 символа символов, как и в моем случае.

Ответ 4

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

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

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

Ответ 5

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

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

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