# constexpr

The keyword *constexpr* specifies that an expression **must** be constant at compile time. This doesn’t necessarily mean that the compiler will take advantage of this and produce optimal code, but at least it might, and it will compute *constexpr* values when forced. In GCC, it appears that you must use at least `-O1`

to generate *constexpr* code, otherwise the full code is evaluated at runtime.

The most simple use is to specify that a variable’s value is given by a *constexpr*:

constexpr int x = 42+42;

Any uses of `x`

are now guaranteed to have the constant value 84 instead of computing `42+42`

at runtime.

There are also *constexpr* functions. A *constexpr* function must be defined in terms of a single return expression, the subexpression of which must be a *constexpr*. For example:

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

Note that this function can still be called with non-const arguments, in that case it will be evaluated at run time. However, it is guaranteed to be a *constexpr* when it is called with *constexpr* arguments.

There are also *constexpr* constructors and member functions for classes.

Suppose that you need some computation to be compile time constant, but the most natural way to express it is with a class, then you can do that with *constexpr* objects, constructors and member functions.

The following is an example of how to use *constexpr* with a class. There is a class `LineSegment`

which represents a line segment, and has a function to compute the midpoint of a line segment.

#include <utility> class LineSegment { public: constexpr LineSegment(double ax, double ay, double bx, double by) : m_ax(ax), m_ay(ay), m_bx(bx), m_by(by) {} constexpr std::pair<double, double> midpoint() { return std::make_pair((m_ax+m_bx)/2, (m_ay+m_by)/2); } private: double m_ax, m_ay, m_bx, m_by; }; constexpr LineSegment line(0,0, 10,10); int main() { return line.midpoint().first; }

By declaring the variable `line`

as a *constexpr*, we are saying that its value is constant, and we are allowing ourselves to query it with *constexpr* member functions. Since it is constant, it must also be constructed with a *constexpr* constructor. The constructor is restricted to having an empty body, and all members must be initialised with an initialiser list whose expressions are also *constexpr*. The midpoint can also be computed with a *constexpr* function since the whole variable is *constexpr*. Finally, we can use `std::pair`

as a *constexpr* because its constructor is also declared as *constexpr*.

Digging into the assembly that is generated, we can verify that the result is as expected.

main: .LFB62: .cfi_startproc movl $5, %eax ret .cfi_endproc

All this does is return 5, which is exactly what we wanted.