What are constant expressions?
§6.6- Constant Expression:
A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.
One of the constraint on the constant expression is
Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated115).
What are the differences between constant expressions and nonmodifiable lvalues?
Non modifiable lvalues are not constant expressions. Non-modifiable values are lvalues that can't be used to modify an object.
int const i = 5;
i
is referring to a const object but it is an lvalue, a special kind of lvalue called non-modifiable lvalue.
Wherever standard says about "lvalue", it actually means "modifiable lvalue" (you won't find this in standard but for the sake of clarity)
Now let me explain it a bit more.
int x = 5;
int const *p;
x
is a non const object and it is a modifiable lvalue. p
is a pointer to a const int
object.
p = &x; // This will raise a warning though and hazardous to do.
Above assignment uses a qualification conversion to convert a value of type pointer to int
into a value of type pointer to const int
.
*p
and x
are two different expression referring to the same object. This abject can be modified using x
--x;
but this can't be done using *p
as it is a non-modifiable lvalues.
--(*p); // Error
One more difference between a constant expression and a non-modifiable lvalue is
int const x = 5;
int *p;
/* Assigning address of a non-modifiable object */
p = &x // Correct
/* Assigning address of a constant expression */
p = &5 // Wrong
Are constant expressions always non-lvalues?
Yes, constant expressions are always non-lvalues, i.e rvalues.
Are nonmodifiable lvalues constant expressions?
No.