Подтвердить что ты не робот

Многосимвольные постоянные предупреждения

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

Пример кода:

int waveHeader = 'EVAW';

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

4b9b3361

Ответ 1

Согласно стандарту (§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-разрядное). Поскольку порядок, в котором символы упакованы в одно целое, не указан, использование многосимвольных констант переносимо.

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

Ответ 2

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

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

Ответ 3

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

-Wno-multichar

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

Ответ 4

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

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

Ответ 5

Простейшее 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" преобразуется в массив, а затем используется анонимное объединение, чтобы дать хорошее имя-символ желаемому числовому результату.