pab*_*977 9 c syntax c99 language-lawyer
在标准C(我的意思是C99或C11)中,我们有所谓的整数常量表达式,它们是常量表达式,其操作数都是常量整数.还有其他约束,以避免表达式中的逗号运算符.
但是,在某些特殊情况下,允许使用其他非整数对象(甚至是非常量对象).
例如,如果将sizeof运算符应用于大小在转换时间中已知的对象,则允许将其作为整数常量表达式的一部分(请注意,sizeof始终返回整数值).
此外,有时也允许显式转换为整数类型.
标准C99建立以下规则:
标准C99,第6.6节(第6节):
整数常量表达式)应具有整数类型,并且只能具有整数常量,操作数,枚举常量,字符常量,结果为整数常量的sizeof表达式,以及作为强制转换的直接操作数的浮点常量.
我的问题是: "浮动常数是演员的直接操作数"的确切含义是什么?
浮点常数类似于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)无法翻译,如预期的那样).
虽然措辞选择不当可能意味着(int) (3.14)不符合整数常量表达式的条件,但我认为这只是措辞中的一个错误。有一个类似的问题,可以说是规范中的错误NULL:它允许是任何空指针常量,其中空指针常量定义为:
void *.然而,为了用作 的定义NULL,表达式应该被正确地加上括号;我所知道的所有现有实现都是这样做的。但严格来说, while(void *)0是一个空指针常量,((void *)0)但不是(它是括号运算符对空指针常量的应用)。
理想情况下,应该在规范中的某个位置添加语言,以澄清括号不会影响此类内容。