In standard C (C99/C11) we have the so-called integer constant expressions, which are constant expressions whose operands are all constant integers.
The following definition applies:
Standard C99, Section 6.6(par.6):
An integer constant expression) shall have integer type and shall only have operands that are integer costants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts.
Standard C99
This appears after the definition of the more general constant expression.
(Since integer constant expression are defined after constant expression, I assume that the former is a particular case of the last.)
On the other hand, conditional expressions are considered constant expressions, constrained by the following rule:
Standard C99, Section 6.6:
Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.
By unrolling the meaning of conditional expression we can fall down to postfix expressions and/or unary expressions.
Now, if we apply these constraints to integer constant expressions, we roughly obtain that they consist of conditional expressions restricted in such a way that every operand is integer/enumeration/character constants (or floating constant immediately preceded by a cast), and such that there are no assignment, increment, decrement, function-call or comma operators.
sizeof
operator and without non-evaluated operands. MY QUESTION IS:
Are the following operators indirectly forbidden in E:
&
(address),*
(indirection),[]
(array-subscript),.
(struct member),->
(pointer to struct members).In addition, are compound literals also forbidden?
Aditional note: I am interested in answering this question for strict conforming programs (C99/C11).
I think that they cannot be in any subexpression of E, but I am not sure if this is completely true. My quick reasoning is as follows:
T
. &
appears before F in E, then &F ins an operand having type "pointer to T", which is not allowed in E (in despite of that F is not an object, but only an integer value, so &
cannot be applied). Thus &
cannot appear in any E. *F
. []
is used to indicate an element inside an array. This means that we would have in E something like A[N]
. Here, N
must be an integer constant expression. However we note that A
is also an operand, but it is an object of type array
, which is not allowed in E. This implies that the array-subscript operator cannot appear in E..
and ->
, it implies they are used inside E as follows: S.memb pS->memb
. Thus, we have the operand S
whose type is struct
or union
and pS
which is a pointer to struct or pointer to union
. But these kind of "operands" are not allowed in E. Do you think that my reasonings are right?
Do you know exceptional cases in that some of these operators or expressions can be [part of] an integer constant expression (as in the restricted case that I denoted E).
An ICE only has to have values (rvalues in the jargon) as primary expressions that constitute it, and no objects (lvalues).
If you build up from there to exclude operators you see that
none of the operators that need an lvalue as operand can be used (assignment, increment, decrement, unary &
)
none of the operators that produce an lvalue can be used either (unary *
, array member []
, member ->
)
the .
operators that needs a struct
as argument, since
there are no literals for struct
Compound literals are a misnomer, they are objects.
Function calls are not allowed either.
Some of these operators can appear in places when they are not evaluated (or not supposed not to be), in particular _Alignof
, the macro offsetof
and some appearances of sizeof
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With