Многосимвольные постоянные предупреждения
Почему это предупреждение? Я думаю, что есть много случаев, когда более понятно использовать multi- char int константы вместо чисел "без значения" или вместо определения константных переменных с одинаковым значением. Когда разбор волновых/tiff/других типов файлов более ясен, чтобы сравнивать значения чтения с некоторыми "EVAW", "данные" и т.д. Вместо их соответствующих значений.
Пример кода:
int waveHeader = 'EVAW';
Почему это дает предупреждение?
Ответы
Ответ 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" преобразуется в массив, а затем используется анонимное объединение, чтобы дать хорошее имя-символ желаемому числовому результату.