Многосимвольные постоянные предупреждения - PullRequest
33 голосов
/ 13 октября 2011

Почему это предупреждение?Я думаю, что есть много случаев, когда более понятно использовать константы multi-char int вместо чисел «без смысла» или вместо определения константных переменных с одинаковым значением.При синтаксическом анализе файлов типа wave / tiff / другие более понятно сравнивать считанные значения с некоторыми значениями EVAW, data и т. Д. Вместо соответствующих значений.

Пример кода:

int waveHeader = 'EVAW';

Почему это дает предупреждение?

Ответы [ 5 ]

36 голосов
/ 13 октября 2011

Согласно стандарту (§6.4.4.4 / 10)

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

long x = '\xde\xad\xbe\xef'; // yes, single quotes

Это действительно ISO 9899: 2011 C. Он компилируется без предупреждения в gcc с -Wall и с предупреждением «константа из нескольких символов» с -pedantic.

Из Википедия :

Многосимвольные константы (например, 'xy') допустимы, хотя редко полезно - они позволяют хранить несколько символов в целом числе (например, 4 Символы ASCII могут помещаться в 32-разрядное целое число, 8 в 64-разрядное). Поскольку порядок, в котором символы упакованы в один int, не указанное, переносимое использование многосимвольных констант затруднено.

Для переносимости не используйте многосимвольные константы с целочисленными типами.

14 голосов
/ 13 октября 2011

Это предупреждение полезно для программистов, которые по ошибке написали бы 'test' там, где они должны были написать "test".

Это случается гораздо чаще, чем программистам, которые действительно хотят использовать константы multi-char int.

13 голосов
/ 13 января 2012

Если вы счастливы, вы знаете, что делаете, и можете принять проблемы переносимости, например, в GCC вы можете отключить предупреждение в командной строке:

-Wno-multichar

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

4 голосов
/ 25 мая 2014

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

Лучше использовать (POD) struct {char[4]};... а затем используйте UDL, такой как "WAVE" _4cc, чтобы легко создавать экземпляры этого класса

0 голосов
/ 04 апреля 2019

Простейший C / C ++ любой компилятор / стандартное совместимое решение, было упомянуто @leftaroundabout в комментариях выше:

int x = *(int*)"abcd";

Или чуть более конкретно:

int x = *(int32_t*)"abcd";

Еще одинрешение, также совместимое с любым компилятором / стандартом C / C ++ (кроме clang ++, у которого есть известная ошибка ):

int x = ((union {char s[5]; int number;}){"abcd"}).number;

/* just a demo check: */
printf("x=%d stored %s byte first\n", x, x==0x61626364 ? "MSB":"LSB");

Здесь строковый литерал "abcd" преобразуется в массив, затеманонимное объединение используется для придания красивого имени символа нужному числовому результату.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...