关于c ++:多字符常量警告

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。在gcc下使用-Wall进行编译时没有警告,而在-pedantic下使用"多字符常量"警告。

从维基百科:

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.

出于可移植性考虑,请勿将整数型常量使用多字符常量。


该警告对于错误地将'test'写入本应写入"test"的程序员很有用。

与实际需要多字符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