关于转换为整数常量表达式(在标准C中)

pab*_*977 9 c syntax c99 language-lawyer

在标准C(我的意思是C99或C11)中,我们有所谓的整数常量表达式,它们是常量表达式,其操作数都是常量整数.还有其他约束,以避免表达式中的逗号运算符.

但是,在某些特殊情况下,允许使用其他非整数对象(甚至是非常量对象).
例如,如果将sizeof运算符应用于大小在转换时间中已知的对象,则允许将其作为整数常量表达式的一部分(请注意,sizeof始终返回整数值).

此外,有时也允许显式转换为整数类型.
标准C99建立以下规则:

标准C99,第6.6节(第6节):

整数常量表达式)应具有整数类型,并且只能具有整数常量,操作数,枚举常量,字符常量,结果为整数常量的sizeof表达式,以及作为强制转换的直接操作数的浮点常量.

标准C99

我的问题是: "浮动常数是演员的直接操作数"的确切含义是什么?

浮点常数类似于3.14e + 3,或者是0x2.11p-5.
也就是说,不是float类型的一般常量表达式,而只是浮点文字.
然后,我明白在上面的定义中只允许这样的事情:

 (int) 3.14
Run Code Online (Sandbox Code Playgroud)

但是不允许涉及浮动文字的操作.
这排除了以下情况:

 (int) -3.14  /* The minus sign is not part of the constant: it is an operator */
 (int) (3.14) /* The parenthesis are an operator acting on the literal 3.14 */
Run Code Online (Sandbox Code Playgroud)

最后一种情况不需要在转换时间中执行任何浮点算术运算,并且相当于没有括号:(int) 3.14.
但是,它不是演员直接操作数.

那么,我们是否必须考虑那(int) (3.14)是[有效整数常量表达式的一部分] (根据定义)?

另一方面,编译器GCC(带选项:-std = c99 -pedantic-errors)给出了这(int) (3.14)是一个有效的整型常量表达式,例如在声明中如下所示:

 #define BITW (int) (3.14)
 struct { unsigned bitfield: BITW } test;  // Translation success
Run Code Online (Sandbox Code Playgroud)

(但是,通过这样做#define BITW (int) (+3.14)无法翻译,如预期的那样).

R..*_*R.. 5

虽然措辞选择不当可能意味着(int) (3.14)不符合整数常量表达式的条件,但我认为这只是措辞中的一个错误。有一个类似的问题,可以说是规范中的错误NULL:它允许是任何空指针常量,其中空指针常量定义为:

  1. 值为 0 的整数常量表达式,或者
  2. 这样的表达式投射到void *.

然而,为了用作 的定义NULL,表达式应该被正确地加上括号;我所知道的所有现有实现都是这样做的。但严格来说, while(void *)0是一个空指针常量,((void *)0)但不是(它是括号运算符对空指针常量的应用)。

理想情况下,应该在规范中的某个位置添加语言,以澄清括号不会影响此类内容。