3

From C in a Nutshell:

Constant expressions

The compiler recognizes constant expressions in source code and replaces them with their values. The resulting constant value must be representable in the expression’s type. You may use a constant expression wherever a simple constant is permitted.

Operators in constant expressions are subject to the same rules as in other expressions. Because constant expressions are evaluated at translation time, though, they cannot contain function calls or operations that modify variables, such as assignments.

  1. What are constant expressions? It doesn't define constant expressions

  2. What are the differences between constant expressions and non-modifiable lvalues (e.g. array names, lvalues which have been declared with const)

  3. Are constant expressions always non-lvalues?

  4. Are non-modifiable lvalues constant expressions?

Community
  • 1
  • 1
Tim
  • 1
  • 141
  • 372
  • 590
  • Any help? https://stackoverflow.com/q/3755524/2173917 – Sourav Ghosh Aug 14 '17 at 15:16
  • I think it's clear that the *important* difference is runtime vs translation time. – Iharob Al Asimi Aug 14 '17 at 15:17
  • Think of constant expression as meaning _literal values_ or operations on literal values in this context. A non-modifiable lvalue is a variable in memory (that's one way to see lvalues), which is defined as being `const`. – Michaël Roy Aug 14 '17 at 15:19
  • @MichaëlRoy: "*which is defined as being `const`*" not necessarily, think of an array. – alk Aug 14 '17 at 15:24
  • An array initializer list is not an array, and must be a constant expression. A non-const array is a set of modifiable lvalues, not a constant expression. – Michaël Roy Aug 14 '17 at 15:41
  • @MichaëlRoy: An array (in its whole) is a non-modifiable lvalue (See [C11 Std 6.3.2.1/1](http://port70.net/~nsz/c/c11/n1570.html#6.3.2.1p1)). – alk Aug 14 '17 at 15:49
  • 4
    I notice that you are keeping asking questions about definitions from different *books* about C. I don't know what is your intention. But the questions you always get are citing the **C standard**. Why won't you just grab a copy of it and try reading it when you have such a question? Also you almost never *accept* the answers. – Eugene Sh. Aug 14 '17 at 16:04
  • @SouravGhosh Thanks. The link is very helpful! – Tim Aug 16 '17 at 03:08
  • @EugeneSh. I apologize for my comments in the other post for what I was not meant to say – Tim Aug 18 '17 at 15:58

4 Answers4

6

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.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • any example where constant expression is not an `nonmodifiable lvalue`? – 0___________ Aug 14 '17 at 16:53
  • @PeterJ; Constant expression can never be an lvalue. A non-modifiable lvalue is an lvalue but it can't be used to modify the object it represent to. The expression `5` is a constant expression and it is an rvalue, not an lvalue (non-modifiable lvalue). – haccks Aug 14 '17 at 17:15
  • Thanks. "A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be." (1) How can I tell if an expression can be evaluated during translation or only runtime? (2) What does "a constant" refer to? Something different from "constant expression"? – Tim Aug 14 '17 at 23:10
  • "Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators". Why can't a constant expression contain any of those? Do them make an expression not "constant"? – Tim Aug 14 '17 at 23:10
  • 1
    @Tim: constant expression means "value calculations only". If a value is assigned somewhere, some incremented or decremented (`++`, `--`), then something is *variable* there and therefore the whole expression is not constant... Also, constant means "compile-time". Function calls occur as if at runtime (even though sometimes compiler *will* resolve those at compile-time, it is not ever required that even the simplest function calls will be inlined). – Antti Haapala -- Слава Україні Aug 15 '17 at 04:49
4
  1. Constant expressions are defined in C11 6.6:

    Description

    2. A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.

    Constraints

    3 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.115)

    4 Each constant expression shall evaluate to a constant that is in the range of representable values for its type.

    There are several types of constant expressions which might be allowed in a place. There are constant expressions that evaluate to

    • an arithmetic constant expression,
      • a special case of this is integer constant expression, which is allowed for example as the size of a (statically allocated) array, or a bitfield width.
    • a null pointer constant,
    • an address constant, or
    • an address constant for a complete object type plus or minus an integer constant expression.
  2. lvalues or locator values (potentially) designate objects. You can take the address of an lvalue. The difference between a modifiable and non-modifiable lvalue is that the latter cannot be used as the left-hand side of an assignment. Or, C11 6.3.2.1p1:

    A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const- qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const- qualified type.

    A non-modifiable lvalue is an lvalue that is not modifiable.

    Constant expressions are just... values. They do not reside in memory - there is no address for number 42 - &42 is meaningless.

  3. constant expressions are thus always non-lvalues. They do not designate objects. You cannot take the address of 6 * 9.

  4. no, but... lvalues of array types implicitly decay into pointers-to-arrays, and these are address constants. However as they're thusly converted they stop being lvalues.

  • Thanks. "Constant expressions are just... values. They do not reside in memory". Not even readonly part of the memory? Then where do constant expressions reside? – Tim Aug 15 '17 at 13:12
  • @Tim the number 6 can be written on paper (then it is an object), but the *idea* of 6 doesn't have a place. Well, the constant expressions reside in memory within the *compiler*; but if you think about a constant expression in a bitfield, say, or a size of an array - the number itself might not be stored directly in the executable at all. – Antti Haapala -- Слава Україні Aug 15 '17 at 14:03
2

I think there are more than one complex questions, let me try to answer it in a simple way (mostly by blatantly copy-pasting from the standard, just creation a retational connection on my own).

1. What are constant expressions?

C11, chapter §6.5, Expressions,

An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.

chapter 6.6, Constant expressions

constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.

and, P4

Each constant expression shall evaluate to a constant that is in the range of representable values for its type.

and, for Lvalues, chapter §6.3.2,

An lvalue is an expression (with an object type other than void) that potentially designates an object

and, for an object, §3.15,

object

region of data storage in the execution environment, the contents of which can represent values

Some constant expressions, such as arrays (array names), string literals or address constants, are lvalues. Otherwise, for the whole range of non-modifiable lvalues, consists of constant object (or object references) and constant expressions.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 1
    ... and arrays. – alk Aug 14 '17 at 15:47
  • Is adress constant `&5` lvalue? – haccks Aug 14 '17 at 15:55
  • @haccks umm..not sure if i'm missing something, but how is `&5` is address constant? `An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator;`...so, this example is not applicable in this case, right sir? – Sourav Ghosh Aug 14 '17 at 16:59
-1

Constant expression is the expression which value is known (can be evaluated) during the compilation

examaples

int a = 5+5+3;  //5 + 5 +3 
char []= "Hello"; // string literal "hello"

Not modificable lvalues are constant objects & constant expessions

Exmaples

const char c;
c = '3';

'3' = c;

Modifiable lvalue has to be addressable (ie you can get their address using &) and assignable ie they can be on the left side of the assignment operator. The only exception are register variables which do no have the address.

0___________
  • 60,014
  • 4
  • 34
  • 74