在C中可以使用64位字符文字吗?
以下代码编译良好:
uint32_t myfunc32() {
uint32_t var = 'asdf';
return var;
}
以下代码给出了警告,“字符常量对于其类型来说太长了”:
uint64_t myfunc64() {
uint64_t var = 'asdfasdf';
return var;
}
实际上,64 位字符文字被 GCC 截断为 32 位常量。64 位字符文字不是 C 的特性吗?我找不到任何关于此的好信息。
编辑:我正在做更多的测试。事实证明,另一个编译器 MetroWerks CodeWarrior 可以按预期编译 64 位字符文字。如果这还不是 GCC 的一个特性,它真的应该是。
回答
64 位字符文字不是 C 的特性吗?
事实上他们不是。根据 C99 §6.4.4.4 第 10 点(此处为第 73 页):
整数字符常量的类型为
int。包含映射到单字节执行字符的单个字符的整数字符常量的值是解释为整数的映射字符表示的数值。包含多个字符(例如,'ab')或包含不映射到单字节执行字符的字符或转义序列的整数字符常量的值
是实现定义的。
因此,字符常量具有 type int,这在大多数现代平台上意味着int32_t. 另一方面,int多字节字符常量产生的实际值是实现定义的,所以你不能真正期望int x = 'abc';,除非您针对特定的编译器和编译器版本。您应该避免在健全的 C 代码中使用此类语句。
根据 GCC 特定的行为,从 GCC 文档中,我们有:
预处理器表达式中字符常量的数值。预处理器和编译器以相同的方式解释字符常量;即转义序列,如
‘a’被赋予它们在目标机器上具有的值。编译器一次计算一个字符的多字符字符常量,将前一个值左移每个目标字符的位数,然后在新字符的位模式中进行 or-ing 截断为目标的宽度特点。最终的位模式被赋予 type
int,因此是有符号的,无论单个字符是否有符号。如果常量中的字符多于适合目标int的字符,编译器会发出警告,并忽略多余的前导字符。例如,
'ab'对于一个8位字符的目标将被解释为‘(int) ((unsigned char) 'a' * 256 + (unsigned char) 'b')’,和'234a'作为‘(int) ((unsigned char) '234' * 256 + (unsigned char) 'a')’。