---
title: "constexpr (C++)"
ms.date: "04/06/2018"
f1_keywords: ["constexpr_cpp"]
ms.assetid: c6458ccb-51c6-4a16-aa61-f69e6f4e04f7
---
# constexpr (C++)
The keyword **constexpr** was introduced in C++11 and improved in C++14. It means *constant expression*. Like **const**, it can be applied to variables so that a compiler error is raised if any code attempts to modify the value. Unlike **const**, **constexpr** can also be applied to functions and class constructors. **constexpr** indicates that the value, or return value, is constant and, if possible, is computed at compile time.
A **constexpr** integral value can be used wherever a const integer is required, such as in template arguments and array declarations. And when a value can be computed at compile time instead of run time, it can help your program run faster and use less memory.
To limit the complexity of compile-time constant computations, and their potential impacts on compilation time, the C++14 standard requires the types in constant expressions to be [literal types](trivial-standard-layout-and-pod-types.md#literal_types).
## Syntax
> **constexpr** *literal-type* *identifier* **=** *constant-expression* **;**
> **constexpr** *literal-type* *identifier* **{** *constant-expression* **}** **;**
> **constexpr** *literal-type* *identifier* **(** *params* **)** **;**
> **constexpr** *ctor* **(** *params* **)** **;**
## Parameters
*params*
One or more parameters, each of which must be a literal type and must itself be a constant expression.
## Return Value
A constexpr variable or function must return a [literal type](trivial-standard-layout-and-pod-types.md#literal_types).
## constexpr variables
The primary difference between const and constexpr variables is that the initialization of a const variable can be deferred until run time. A constexpr variable must be initialized at compile time. All constexpr variables are const.
- A variable can be declared with **constexpr**, if it has a literal type and is initialized. If the initialization is performed by a constructor, the constructor must be declared as **constexpr**.
- A reference may be declared as constexpr if the object that it references has been initialized by a constant expression and any implicit conversions that are invoked during initialization are also constant expressions.
- All declarations of a **constexpr** variable or function must have the **constexpr** specifier.
```cpp
constexpr float x = 42.0;
constexpr float y{108};
constexpr float z = exp(5, 3);
constexpr int i; // Error! Not initialized
int j = 0;
constexpr int k = j + 1; //Error! j not a constant expression
```
## constexpr functions
A **constexpr** function is one whose return value can be computed at compile time when consuming code requires it. Consuming code requires the return value at compile time, for example, to initialize a **constexpr** variable or provide a non-type template argument. When its arguments are **constexpr** values, a **constexpr** function produces a compile-time constant. When called with non-**constexpr** arguments, or when its value isn't required at compile-time, it produces a value at run time like a regular function. (This dual behavior saves you from having to write **constexpr** and non-**constexpr** versions of the same function.)
A **constexpr** function or constructor is implicitly **inline**.
The following rules apply to constexpr functions:
- A **constexpr** function must accept and return only [literal types](trivial-standard-layout-and-pod-types.md#literal_types).
- A **constexpr** function can be recursive.
- It cannot be [virtual](../cpp/virtual-cpp.md). A constructor cannot be defined as constexpr if the enclosing class has any virtual base classes.
- The body can be defined as `= default` or `= delete`.
- The body can contain no **goto** statements or try blocks.
- An explicit specialization of a non-constexpr template can be declared as **constexpr**:
- An explicit specialization of a **constexpr** template does not have to also be **constexpr**:
The following rules apply to **constexpr** functions in Visual Studio 2017 and later:
- It may contain **if** and **switch** statements, and all looping statements including **for**, range-based for, **while**, and **do-while**.
- It may contain local variable declarations, but the variable must be initialized, must be a literal type, and cannot be static or thread-local. The locally declared variable isn't required to be const and may mutate.
- A constexpr non-static member function is not required to be implicitly const.
```cpp
constexpr float exp(float x, int n)
{
return n == 0 ? 1 :
n % 2 == 0 ? exp(x * x, n / 2) :
exp(x * x, (n - 1) / 2) * x;
};
```
> [!TIP]
> In the Visual Studio debugger, when debugging a non-optimised Debug build, you can tell whether a **constexpr** function is being evaluated at compile time by putting a breakpoint inside it. If the breakpoint is hit, the function was called at run-time. If not, then the function was called at compile time.
## extern constexpr
The [/Zc:externConstexpr](../build/reference/zc-externconstexpr.md) compiler option causes the compiler to apply [external linkage](../c-language/external-linkage.md) to variables declared by using **extern constexpr**. In earlier versions of Visual Studio, and by default or if **/Zc:externConstexpr-** is specified, Visual Studio applies internal linkage to **constexpr** variables even if the **extern** keyword is used. The **/Zc:externConstexpr** option is available starting in Visual Studio 2017 Update 15.6. and is off by default. The /permissive- option does not enable /Zc:externConstexpr.
## Example
The following example shows **constexpr** variables, functions, and a user-defined type. In the last statement in main(), the **constexpr** member function GetValue() is a run-time call because the value isn't required to be known at compile time.
```cpp
#include
using namespace std;
// Pass by value
constexpr float exp(float x, int n)
{
return n == 0 ? 1 :
n % 2 == 0 ? exp(x * x, n / 2) :
exp(x * x, (n - 1) / 2) * x;
};
// Pass by reference
constexpr float exp2(const float& x, const int& n)
{
return n == 0 ? 1 :
n % 2 == 0 ? exp2(x * x, n / 2) :
exp2(x * x, (n - 1) / 2) * x;
};
// Compile-time computation of array length
template
constexpr int length(const T(&ary)[N])
{
return N;
}
// Recursive constexpr function
constexpr int fac(int n)
{
return n == 1 ? 1 : n*fac(n - 1);
}
// User-defined type
class Foo
{
public:
constexpr explicit Foo(int i) : _i(i) {}
constexpr int GetValue()
{
return _i;
}
private:
int _i;
};
int main()
{
// foo is const:
constexpr Foo foo(5);
// foo = Foo(6); //Error!
// Compile time:
constexpr float x = exp(5, 3);
constexpr float y { exp(2, 5) };
constexpr int val = foo.GetValue();
constexpr int f5 = fac(5);
const int nums[] { 1, 2, 3, 4 };
const int nums2[length(nums) * 2] { 1, 2, 3, 4, 5, 6, 7, 8 };
// Run time:
cout << "The value of foo is " << foo.GetValue() << endl;
}
```
## Requirements
Visual Studio 2015
## See also
[Declarations and Definitions](../cpp/declarations-and-definitions-cpp.md)
[const](../cpp/const-cpp.md)