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?
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?
I believe there is a difference. Let's rename them so that we can talk about them more easily:
Both
PI1
andPI2
are constant, meaning you can not modify them. However onlyPI2
is a compile-time constant. It shall be initialized at compile time.PI1
may be initialized at compile time or run time. Furthermore, onlyPI2
can be used in a context that requires a compile-time constant. For example:but:
and:
but:
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.
A constexpr symbolic constant must be given a value that is known at compile time. For example:
To handle cases where the value of a “variable” that is initialized with a value that is not known at compile time but never changes after initialization, C++ offers a second form of constant (a const). For Example:
Such “const variables” are very common for two reasons:
Reference : "Programming: Principles and Practice Using C++" by Stroustrup
constexpr indicates a value that's constant and known during compilation.
const indicates a value that's only constant; it's not compulsory to know during compilation.
Note that const doesn’t offer the same guarantee as constexpr, because const objects need not be initialized with values known during compilation.
All constexpr objects are const, but not all const objects are constexpr.
If you want compilers to guarantee that a variable has a value that can be used in contexts requiring compile-time constants, the tool to reach for is constexpr, not const.
No difference here, but it matters when you have a type that has a constructor.
s0
is a constant, but it does not promise to be initialized at compile-time.s1
is markedconstexpr
, so it is a constant and, becauseS
's constructor is also markedconstexpr
, 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