Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const vs constexpr on variables

Is there a difference between the following definitions?

const     double PI = 3.141592653589793; constexpr double PI = 3.141592653589793; 

If not, which style is preferred in C++11?

like image 901
fredoverflow Avatar asked Nov 12 '12 15:11

fredoverflow


People also ask

Should I use const or constexpr?

const applies for variables, and prevents them from being modified in your code. constexpr tells the compiler that this expression results in a compile time constant value, so it can be used in places like array lengths, assigning to const variables, etc.

Are constexpr variables const?

A constexpr variable must be initialized at compile time. All constexpr variables are const . A variable can be declared with constexpr , when it has a literal type and is initialized. If the initialization is performed by a constructor, the constructor must be declared as constexpr .

Why is constexpr over const?

const can only be used with non-static member function whereas constexpr can be used with member and non-member functions, even with constructors but with condition that argument and return type must be of literal types.

Does constexpr improve performance?

Understanding constexpr Specifier in C++ constexpr is a feature added in C++ 11. The main idea is a performance improvement of programs by doing computations at compile time rather than run time.


Video Answer


2 Answers

I believe there is a difference. Let's rename them so that we can talk about them more easily:

const     double PI1 = 3.141592653589793; constexpr double PI2 = 3.141592653589793; 

Both PI1 and PI2 are constant, meaning you can not modify them. However only PI2 is a compile-time constant. It shall be initialized at compile time. PI1 may be initialized at compile time or run time. Furthermore, only PI2 can be used in a context that requires a compile-time constant. For example:

constexpr double PI3 = PI1;  // error 

but:

constexpr double PI3 = PI2;  // ok 

and:

static_assert(PI1 == 3.141592653589793, "");  // error 

but:

static_assert(PI2 == 3.141592653589793, "");  // ok 

As to which you should use? Use whichever meets your needs. Do you want to ensure that you have a compile time constant that can be used in contexts where a compile-time constant is required? Do you want to be able to initialize it with a computation done at run time? Etc.

like image 81
Howard Hinnant Avatar answered Sep 28 '22 12:09

Howard Hinnant


No difference here, but it matters when you have a type that has a constructor.

struct S {     constexpr S(int); };  const S s0(0); constexpr S s1(1); 

s0 is a constant, but it does not promise to be initialized at compile-time. s1 is marked constexpr, so it is a constant and, because S's constructor is also marked constexpr, it will be initialized at compile-time.

Mostly this matters when initialization at runtime would be time-consuming and you want to push that work off onto the compiler, where it's also time-consuming, but doesn't slow down execution time of the compiled program

like image 41
Pete Becker Avatar answered Sep 28 '22 12:09

Pete Becker