在标准C(C99 / C11)中,我们有所谓的整数常量表达式,它们是常量表达式,其操作数都是常量整数。
以下定义适用:
标准C99,第6.6节(第6节):
整数常量表达式)应具有整数类型且必须 只有整数常量,枚举常量的操作数, 字符常量,sizeof表达式,其结果是整数 常量和浮动常量,它们是直接操作数 管型。
在更一般的常量表达式的定义之后出现 (由于整数常量表达式是在常量表达式之后定义的,我假设前者是最后一个的特殊情况。)
另一方面,条件表达式被视为常量表达式,受以下规则约束:
标准C99,第6.6节:
常量表达式不应包含赋值,增量, 递减,函数调用或逗号运算符,除非它们是 包含在未评估的子表达式中。
通过展开条件表达式的含义,我们可以归结为后缀表达式和/或一元表达式。
现在,如果我们将这些约束应用于整数常量表达式,我们粗略地得出它们由条件表达式组成,这些条件表达式的限制使得每个操作数都是整数/枚举/字符常量(或浮点常量)紧跟在演员之后,并且没有赋值,递增,递减,函数调用或逗号运算符。
sizeof
运算符且没有未计算的操作数。 我的问题是:
以下操作符是否在 E :
&
(地址),*
(间接),[]
(array-subscript),.
(struct member),->
(指向结构成员的指针)。另外,复合文字是否也被禁止?
备注:我有兴趣回答严格符合程序的问题(C99 / C11)。
我认为它们不能处于 E 的任何子表达式中,但我不确定这是否完全正确。我的快速推理如下:
T
。 &
出现在 F 之前 E ,那么& F 就会出现一个类型为“指针”的操作数到T“, E 中不允许(尽管 F 不是对象,但只是整数值,因此无法应用&
)。因此&
不能出现在任何 E 中。 *F
无意义。 []
用于表示数组内的元素。这意味着我们会在 E 中拥有A[N]
之类的东西。这里,N
必须是整数常量表达式。但是我们注意到A
也是一个操作数,但它是array
类型的对象, E 中不允许这样做。这意味着数组下标运算符不能出现在 E 。.
和->
,则表示它们在 E 中使用,如下所示:{{1} }。因此,我们有操作数S.memb pS->memb
,其类型为S
或struct
,union
为pS
。但 E 中不允许使用这些“操作数”。 你认为我的推理是对的吗? 您是否知道特殊情况,其中一些运算符或表达式可以是整数常量表达式的一部分(如我所指示的 E 的限制情况)。
答案 0 :(得分:2)
ICE只需要将值(行话中的rvalues)作为构成它的主表达式,而不是对象(左值)。
如果你从那里建立以排除运营商,你会看到
不能使用左值作为操作数的运算符(赋值,递增,递减,一元&
)
任何产生左值的运算符都不能使用(一元*
,数组成员[]
,成员->
)
需要.
作为参数的struct
运算符,因为
struct
复合文字是用词不当,它们是对象。
也不允许进行函数调用。
其中一些运算符可以在未评估(或不应该)的位置出现,特别是_Alignof
,宏offsetof
和某些sizeof
的出现。