根据C标准,负整数字面值被解释为单个字面值还是运算符和字面值?

4

C标准/编译器是如何解释负整数的 - 作为一个单独的文字,还是一元运算符和数字文字?

例如,-16 被解释为 -16 还是 -(16)


2
作为一个好奇心,C标准库通常定义INT_MIN的原因是像这样:#define INT_MIN (-2147483647 - 1),因为正数2147483648太大了,无法适应类型int,所以它会变成long或其他类型。这对于各种隐式类型原因来说是不好的,例如从宽类型赋值到窄类型。而将一元运算符-添加到2147483648上也没有帮助,因为整数常量在那时已经具有long类型了。 - Lundin
C在其他方面使用“字面量”。C将16识别为“整数常量”。 - undefined
2个回答

5

-16包含两个标记:操作符-和一个值为16,类型为int整数常量


尝试以下代码。即使是库常量也要经过精心构造,以避免-2147483648,这个值与(-0x7fffffff-1)相同,但是它是一个更宽的类型,因为2147483648超过了int范围。

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
puts(TOSTRING(INT_MIN));

输出

(-0x7fffffff-1)

0x80000000没有更宽的类型:在32位架构上,它的类型是unsigned,宽度与int相同,但是是不同的类型。使用“(-0x7fffffff-1)”这个迂回表达式可以计算出类型为intINT_MIN - chqrlie
1
@chqrlie 当然可以。回答已经修改。 - chux - Reinstate Monica

5
C 2018 6.4.4.1 1 展示了整数常量的语法。它指出,一个 integer-constant 是以下其中之一:
  • decimal-constant integer-suffixopt
  • octal-constant integer-suffixopt
  • hexadecimal-constant integer-suffixopt
由于我们只关心这些常量的开头,integer-suffix 不相关。以下语法规则显示:
  • decimal-constantnonzero-digit 开始,当然可以是 1, 2, 3, 4, 5, 6, 7, 89
  • octal-constant0 开头。
  • hexadecimal-constant0x0X 开头。
因此,没有 integer-constant-+ 开头。 -16 被解析为一元运算符 - 后面跟着整数常量 16。这形成了一个整数常量表达式,如 C 2018 6.6 6 所述,它表示:

… 一个 integer constant expression 必须具有整数类型,并且只能具有整数常量、枚举常量、字符常量、结果为整数常数的 sizeof 表达式、_Alignof 表达式和是转换的直接操作数的浮点常量。


1
值得注意的是,减号的否定是由6.5.3.3中描述的一元负运算符的结果。 - Willis Hershey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接