Why is this a warning? I think there are many cases when is more clear to use multi-char int constants instead of \"no meaning\" numbers or instead of defining const variabl
If you want to disable this warning it is important to know that there are two related warning parameters in GCC and Clang: GCC Compiler options -wno-four-char-constants and -wno-multichar
If you're happy you know what you're doing and can accept the portability problems, on GCC for example you can disable the warning on the command line:
-Wno-multichar
I use this for my own apps to work with AVI and MP4 file headers for similar reasons to you.
This warning is useful for programmers that would mistakenly write 'test'
where they should have written "test"
.
This happen much more often than programmers that do actually want multi-char int constants.
According to the standard (§6.4.4.4/10)
The value of an integer character constant containing more than one character (e.g., 'ab'), [...] is implementation-defined.
long x = '\xde\xad\xbe\xef'; // yes, single quotes
This is valid ISO 9899:2011 C. It compiles without warning under gcc
with -Wall
, and a “multi-character character constant” warning with -pedantic
.
From Wikipedia:
Multi-character constants (e.g. 'xy') are valid, although rarely useful — they let one store several characters in an integer (e.g. 4 ASCII characters can fit in a 32-bit integer, 8 in a 64-bit one). Since the order in which the characters are packed into one int is not specified, portable use of multi-character constants is difficult.
For portability sake, don't use multi-character constants with integral types.
Even if you're willing to look up what behavior your implementation defines, multi-character constants will still vary with endianness.
Better to use a (POD) struct { char[4] }; ... and then use a UDL like "WAVE"_4cc to easily construct instances of that class
Simplest C/C++ any compiler/standard compliant solution, was mentioned by @leftaroundabout in comments above:
int x = *(int*)"abcd";
Or a bit more specific:
int x = *(int32_t*)"abcd";
One more solution, also compliant with C/C++ compiler/standard since C99 (except clang++, which has a known bug):
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");
Here anonymous union is used to give a nice symbol-name to the desired numeric result, "abcd" string is used to initialize the lvalue of compound literal (C99).