# Constant expressions

From cppreference.com
< c‎ | language

Several varieties of expressions are known as constant expressions

### Preprocessor constant expression

The expression following #if or #elif must expand to

- operators other than assignment, increment, decrement, function-call, or comma whose arguments are preprocessor constant expressions
- integer constants
- character constants
- the special preprocessor operator `defined`

Character constants, when evaluated in `#if`-expressions, may be interpreted in the source character set, the execution character set, or some other implementation-defined character set.

Integer arithmetic in `#if`-expressions is performed using the semantics of intmax_t for signed types and uintmax_t for unsigned types. | (since C99)

### Integer constant expression

An integer constant expression is an expression that consists only of

- operators other than assignment, increment, decrement, function-call, or comma, except that cast operators can only cast arithmetic types to integer types
- integer constants
- enumeration constants
- character constants
- floating constants, but only if they are immediately used as operands of casts to integer type
- sizeof operators whose operands are not VLA (since C99)

- _Alignof operators

(since C11)

Integer constant expressions are evaluated at compile time. The following contexts require expressions that are known as integer constant expressions':

- The size of a bit field.
- The value of an enumeration constant
- The `case` label of a switch statement
- The size of a non-VLA (since C99) array
- Integer to pointer implicit conversion.

- The index in an array designator

(since C99)

- The first argument of _Static_assert
- The integer argument of _Alignas

(since C11)

### Static initializer

Expressions that are used in the initializers of objects with static and thread_local storage duration must be expressions that may be one of the following

1) arithmetic constant expression, which is an expression of any arithmetic type that consists of

  - operators other than assignment, increment, decrement, function-call, or comma, except that cast operators must be converting arithmetic types to other arithmetic types
  - integer constants
  - floating constants
  - enumeration constants
  - character constants
  - sizeof operators whose operands are not VLA (since C99)

  - _Alignof operators

(since C11)

2) the null pointer constant NULL
3) address constant expression, which is

  - a null pointer
  - lvalue designating an object of static storage duration or a function designator, converted to a pointer either
    - by using the unary address-of operator
    - by casting an integer constant to a pointer
    - by array-to-pointer or function-to-pointer implicit conversion

4) address constant expression of some complete object type, plus or minus an integer constant expression

Unlike with integer constant expressions, static initializer expressions are not required to be evaluated at compile time; the compiler is at liberty to turn such initializers into executable code which is invoked prior to program startup.

    static int i = 2 || 1 / 0; // initializes i to value 1

| This section is incomplete Reason: other mini-examples

The value of a floating-point static initializer is never less accurate than the value of the same expression executed at run time, but it may be better.

### Floating-point constant expressions

Arithmetic constant expressions of floating-point types that are not used in static initializers are always evaluated as-if during run-time and are affected by the current rounding (if FENV_ACCESS is on) and report errors as specified in math_errhandling.

    void f(void)
    {
    #pragma STDC FENV_ACCESS ON
        static float x = 0.0/0.0; // static initializer: does not raise an exception
        float w[] = { 0.0/0.0 }; // raises an exception
        float y = 0.0/0.0; // raises an exception
        double z = 0.0/0.0; // raises an exception
    }

### Notes

If an expression evaluates to a value that is not representable by its type, it cannot be used as a constant expression.

### References

- C11 standard (ISO/IEC 9899:2011):

  - 6.6 Constant expressions (p: 106-107)

- C99 standard (ISO/IEC 9899:1999):

  - 6.6 Constant expressions (p: 95-96)

- C89/C90 standard (ISO/IEC 9899:1990):

  - 3.4 CONSTANT EXPRESSIONS

### See also

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=c/language/constant_expression&oldid=79147"