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.
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.
- By simplicity, let us suppose that E is a such expression, without any
sizeofoperator 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:
- If F is an integer constant subexpression of E, then F has, by definition, an integer type
T. - If the unary operator
&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. - Since F has not any pointer type, it has no sense the expression
*F. - A subscript operator
[]is used to indicate an element inside an array. This means that we would have in E something likeA[N]. Here,Nmust be an integer constant expression. However we note thatAis also an operand, but it is an object of typearray, which is not allowed in E. This implies that the array-subscript operator cannot appear in E. - If we have in E the operators
.and->, it implies they are used inside E as follows:S.memb pS->memb. Thus, we have the operandSwhose type isstructorunionandpSwhich is apointer to struct or pointer to union. But these kind of "operands" are not allowed in E. - Compound literals are not allowed in E, because they are lvalues, which implies they will have an address when the program runs. Since such an address cannot be known by the compiler, the expression involving a compound literal is not considered a constant.
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).