Multi-character constant warnings
为什么这是警告? 我认为在许多情况下,使用多字符int常量代替"无意义"数字或用相同的值定义const变量更为明确。 解析wave / tiff /其他文件类型时,更清晰地将读取的值与某些" EVAW"," data"等进行比较,而不是将它们的对应值进行比较。
样例代码:
1 | int waveHeader = 'EVAW'; |
为什么这会发出警告?
根据标准(§6.4.4.4/ 10)
The value of an integer character constant containing more than one
character (e.g., 'ab'), [...] is implementation-defined.
1 | long x = '\\xde\\xad\\xbe\\xef'; // yes, single quotes |
这是有效的ISO 9899:2011C。在
从维基百科:
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.
出于可移植性考虑,请勿将整数型常量使用多字符常量。
该警告对于错误地将
与实际需要多字符int常量的程序员相比,这种情况发生的频率更高。
如果您很高兴知道自己在做什么并且可以接受可移植性问题,例如在GCC上,可以在命令行上禁用警告:
1 | -Wno-multichar |
由于与您类似的原因,我将其用于自己的应用程序以与AVI和MP4文件头一起使用。
即使您愿意查找实现定义的行为,多字符常量仍会随字节顺序而变化。
最好使用(POD)结构{char [4]}; ...,然后使用" WAVE" _4cc之类的UDL轻松构造该类的实例
@leftaroundabout在上面的评论中提到了最简单的C / C ++任何编译器/标准兼容解决方案:
1 | int x = *(int*)"abcd"; |
或更具体一点:
1 | int x = *(int32_t*)"abcd"; |
另一种解决方案,自C99以来也与C / C ++编译器/标准兼容(clang ++除外,该漏洞具有已知错误):
1 2 3 4 5 | int x = ((union {char s[5]; int number;}){"abcd"}).number; /* just a demo check: */ printf("x=%d stored %s byte first\ ", x, x==0x61626364 ?"MSB":"LSB"); |
在这里,匿名联合用于为所需的数字结果提供一个好的符号名," abcd"字符串用于初始化复合文字(C99)的左值。
如果要禁用此警告,重要的是要知道GCC和Clang中有两个相关的警告参数:GCC编译器选项-wno-four-char-constants和-wno-multichar