Multi-character constant warnings

前端 未结 6 1447
别那么骄傲
别那么骄傲 2020-11-22 09:26

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

相关标签:
6条回答
  • 2020-11-22 09:50

    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

    0 讨论(0)
  • 2020-11-22 09:51

    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.

    0 讨论(0)
  • 2020-11-22 09:55

    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.

    0 讨论(0)
  • 2020-11-22 09:57

    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.

    0 讨论(0)
  • 2020-11-22 09:59

    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

    0 讨论(0)
  • 2020-11-22 10:08

    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).

    0 讨论(0)
提交回复
热议问题