# constexpr functions

suggest changeA function that is declared `constexpr`

is implicitly inline and calls to such a function potentially yield constant expressions. For example, the following function, if called with constant expression arguments, yields a constant expression too:

```
constexpr int Sum(int a, int b)
{
return a + b;
}
```

Thus, the result of the function call may be used as an array bound or a template argument, or to initialize a `constexpr`

variable:

```
int main()
{
constexpr int S = Sum(10,20);
int Array[S];
int Array2[Sum(20,30)]; // 50 array size, compile time
}
```

Note that if you remove `constexpr`

from function’s return type specification, assignment to `S`

will not work, as `S`

is a `constexpr`

variable, and must be assigned a compile-time const. Similarly, size of array will also not be a constant-expression, if function `Sum`

is not `constexpr`

.

Interesting thing about `constexpr`

functions is that you may also use it like ordinary functions:

```
int a = 20;
auto sum = Sum(a, abs(-20));
```

`Sum`

will not be a `constexpr`

function now, it will be compiled as an ordinary function, taking variable (non-constant) arguments, and returning non-constant value. You need not to write two functions.

It also means that if you try to assign such call to a non-const variable, it won’t compile:

```
int a = 20;
constexpr auto sum = Sum(a, abs(-20));
```

The reason is simple: `constexpr`

must only be assigned a compile-time constant. However, the above function call makes `Sum`

a non-`constexpr`

(R-value is non-const, but L-value is declaring itself to be `constexpr`

).

The `constexpr`

function **must** also return a compile-time constant. Following will not compile:

```
constexpr int Sum(int a, int b)
{
int a1 = a; // ERROR
return a + b;
}
```

Because `a1`

is a non-constexpr *variable*, and prohibits the function from being a true `constexpr`

function. Making it `constexpr`

and assigning it `a`

will also not work - since value of `a`

(incoming parameter) is still not yet known:

```
constexpr int Sum(int a, int b)
{
constexpr int a1 = a; // ERROR
..
```

Furthermore, following will also not compile:

```
constexpr int Sum(int a, int b)
{
return abs(a) + b; // or abs(a) + abs(b)
}
```

Since `abs(a)`

is not a constant expression (even `abs(10)`

will not work, since `abs`

is not returning a `constexpr int`

!

What about this?

```
constexpr int Abs(int v)
{
return v >= 0 ? v : -v;
}
constexpr int Sum(int a, int b)
{
return Abs(a) + b;
}
```

We crafted our own `Abs`

function which is a `constexpr`

, and the body of `Abs`

also doesn’t break any rule. Also, at the call site (inside `Sum`

), the expression evaluates to a `constexpr`

. Hence, the call to `Sum(-10, 20)`

will be a compile-time constant expression resulting to `30`

.