我不知道C和C ++允许multicharacter literal
:不是'c'(C中的 int 类型,C ++中的 char ),但是'tralivali'(类型 int !)
enum
{
ActionLeft = 'left',
ActionRight = 'right',
ActionForward = 'forward',
ActionBackward = 'backward'
};
标准说:
C99 6.4.4.4p10:“一个人的价值 整数字符常量包含 不止一个字符(例如'ab'), 或包含角色或逃脱 不映射到a的序列 单字节执行字符,是 实现定义“。
我发现它们在C4 engine中被广泛使用。但是,当我们谈论平台独立序列化时,我认为它们并不安全。 Thay也会让人感到困惑,因为看起来像字符串。那么什么是多字符文字的使用范围,它们对某些东西有用吗?他们是否只是为了与C代码兼容而使用C ++?它们被认为是 goto 运算符的不良特性吗?
答案 0 :(得分:27)
它可以更容易地选择内存转储中的值。
示例:
enum state { waiting, running, stopped };
VS
enum state { waiting = 'wait', running = 'run.', stopped = 'stop' };
以下语句后的内存转储:
s = stopped;
可能看起来像:
00 00 00 02 . . . .
在第一种情况下,vs:
73 74 6F 70 s t o p
使用多字符文字。 (当然是否说“停止”或“花盆”取决于字节顺序)
答案 1 :(得分:17)
我不知道这有多广泛使用,但“实现定义”对我来说是一个大红旗。据我所知,这可能意味着实现可以选择忽略您的角色指定,只是在需要时分配正常的递增值。它可能会做一些“更好”的事情,但你不能依赖编译器(甚至编译器版本)的那种行为。至少“goto”具有可预测的(如果不合需要的)行为......
无论如何,这是我的2c。
编辑:关于“实现定义”:
来自Bjarne Stroustrup's C++ Glossary:
实现定义 - 一个方面 C ++定义的语义 每个实现而不是 标准中规定的每一个 实现。一个例子是尺寸 一个int(必须至少16 比特但可以更长)。避免 实现定义的行为 只要有可能。也可以看看: 未定义。 TC ++ PL C.2。
...也
undefined - C ++的一个方面 没有合理的语义 行为是必需的。一个例子是 取消引用带有值的指针 零。避免未定义的行为。看到 还:实施定义。 TC ++ PL C.2。
我认为这意味着评论是正确的:它至少应该编译,尽管未指定任何内容。请注意定义中的建议。
答案 2 :(得分:5)
我见过并使用过的四个字符文字。它们映射到4个字节=一个32位字。如上所述,它对于调试目的非常有用。它们可以在带有整数的switch / case语句中使用,这很不错。
这(4个字符)非常标准(至少由GCC和VC ++支持),尽管结果(编译的实际值)可能因实现而异。
但超过4个字符?我不会用。
更新:从C4页面:“对于我们的简单操作,我们只提供一些值的枚举,这是通过指定四个字符的常量在C4中完成的”。所以他们使用4个字符文字,就像我的情况一样。
答案 3 :(得分:3)
多字符文字允许通过字符中的等效表示来指定int
值。对于枚举,FourCC代码和标记以及非类型模板参数很有用。使用多字符文字,可以直接在源中键入FourCC code,这很方便。
gcc中的实现在https://gcc.gnu.org/onlinedocs/cpp/Implementation-defined-behavior.html中描述。请注意,该值将被截断为int
类型的大小,如果您的整数为4个字符宽,则为'efgh' == 'abcdefgh'
,尽管gcc会对溢出的文字发出警告。
不幸的是,如果传递-pedantic
,gcc将在所有多字符文字上发出警告,因为它们的行为是实现定义的。正如您在上面所看到的,如果切换实现,可能会改变两个多字符文字的相等性。
答案 4 :(得分:3)
在C++14 specification draft N4527第2.13.3节,第2条:
...包含多个c-char的普通字符文字是多字符文字。包含单个c-char的多字符文字或普通字符文字在执行字符集中无法表示,它是有条件支持的,类型为int,并且具有实现定义的值。
您问题的先前答案主要涉及支持多字符文字的真实机器。具体来说,在int
为4字节的平台上,四字节多字符很好,可以方便使用,如Ferrucio的mem转储示例所示。但是,由于无法保证其在其他平台上的工作或工作方式相同,因此对于便携式程序,不应使用多字符文字。
答案 5 :(得分:0)
令人难以置信的是,我认识的每个编译器都将定义为4个字符的UINT的第一个字符放在低有效字节(小印度)中,但是Visual C却以相反的方向进行操作
// file signature
#define SFKFILE_SIGNATURE 'SFPK' (S=53)
// check header
if (out_FileHdr->Signature != SFKFILE_SIGNATURE)
Borland:4B504653 4B504653
Watcom:4B504653 4B504653
VisualC:4B504653 5346504B