操作员间接禁止(或不?)定义整数常量表达式(在C中)

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

在标准C(C99/C11)中,我们有所谓的整数常量表达式,它们是常量表达式,其操作数都是常量整数.

以下定义适用:

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

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

标准C99

这在更一般的常量表达式的定义之后出现.
(由于在常量表达式之后定义了整型常量表达式,我假设前者是最后一个的特殊情况.)

另一方面,条件表达式被视为常量表达式,受以下规则约束:

标准C99,第6.6节:

常量表达式不应包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在未评估的子表达式中.

通过展开条件表达式的含义,我们可以归结为后缀表达式和/或一元表达式.

现在,如果我们将这些约束应用于整数常量表达式,我们粗略地得到它们由条件表达式组成,这些条件表达式的限制使得每个操作数都是整数/枚举/字符常量(或浮动常量紧跟在强制转换之前),并且没有赋值,递增,递减,函数调用或逗号运算符.

  • 简单来说,让我们假设E是一个这样的表达式,没有任何sizeof运算符,也没有未计算的操作数.

我的问题是:E中
是否间接禁止以下操作员:

  • & (地址),
  • * (间接),
  • [] (数组下标),
  • . (结构成员),
  • -> (指向struct成员的指针).

另外,复合文字是否也被禁止?

备注:我有兴趣回答严格符合程序的问题(C99/C11).

我认为它们不能处于E的任何子表达式中,但我不确定这是否完全正确.我的快速推理如下:

  • 如果FE的整数常量子表达式,则根据定义F具有整数类型T.
  • 如果一元运算符&出现在E中的F之前,则&F输入一个操作数,其类型为"指向T的指针",这在E中是不允许的(尽管F不是一个对象,但只是一个整数值,所以不能应用).因此不能出现在任何E中.&&
  • 由于F没有任何指针类型,因此表达式无意义*F.
  • 下标运算符[]用于指示数组内的元素.这意味着我们会在E中拥有类似的东西A[N].这里,N必须是整数常量表达式.但是我们注意到它A也是一个操作数,但它是一个类型的对象,arrayE中是不允许的.这意味着数组下标运算符不能出现在E中.
  • 如果我们在Ë运营商.->,这意味着他们将在内部使用é如下:S.memb pS->memb.因此,我们有操作S类型为structunion并且pS这是一个pointer to struct or pointer to union.但E中不允许使用这种"操作数" .
  • E中不允许使用复合文字,因为它们是左值,这意味着它们在程序运行时会有一个地址.由于编译器无法知道这样的地址,因此涉及复合文字的表达式不被视为常量.

你认为我的推理是对的吗?
您是否知道这些特殊情况,其中一些运算符或表达式可以是整数常量表达式的一部分(如我在E表示的限制情况).

Jen*_*edt 3

ICE 只需要具有值(行话中的右值)作为构成它的主要表达式,并且不需要对象(左值)。

如果您从那里开始排除运算符,您会看到

  • 不能使用需要左值作为操作数的运算符(赋值、递增、递减、一元&

  • 也不能使用产生左值的运算符(一元*、数组成员[]、成员->

  • .需要 a 作为参数的运算符,struct因为

    • 没有文字struct

    • 复合文字是用词不当,它们是对象。

    • 函数调用也是不允许的。

其中一些运算符可能会出现在未计算(或不应该计算)的位置,特别是_Alignofoffsetof和 的某些出现sizeof