The C++ Programming Language Fourth Edition - Bjarne Stroustrup: (emphasis mine)
2.2.3. Constants
In a few places, constant expressions are required by language rules
(e.g., array bounds (§2.2.5, §7.3), case labels (§2.2.4, §9.4.2), some
template arguments (§25.2), and constants declared using constexpr).
In other cases, compile-time evaluation is important for performance.
Independently of performance issues, the notion of immutability (of an object with an unchangeable state) is an important design concern
(§10.4).
It seems that Stroustrup is suggesting here that constexpr
ensures immutability of an object better than a traditional const
declaration. Is this correct? Are there ways in which constexpr
can be more secure/less volatile than const
, or does Stroustrup simply mean that since there are ways to use constexpr
that are not supported with const
(see Is constexpr really needed?), in those cases immutability can be ensured using constexpr
?
He states in the beginning of the section:
C++ supports two notions of immutability
and he lists const and constexpr, I don't believe he is attempting to say that constexpr ensures immutability better than const they just have different features, although I admit the fact the sentence cites section 10.4
Constant Expressions does seem to imply that, that interpretation is inconsistent with the rest of the text.
A variable that is const
is immutable in that scope but may not be const
in the larger scope(for example a const reference parameter to a function) and that is perhaps a subtle distinction he is attempting to make, he says that const
:
is used primarily to specify interfaces
whereas constexpr
:
This is used primarily to specify constants, to allow placement of data in read-only memory
Any variable that is constexpr
should be evaluated at compile time and thus usable where constant expressions are required whereas a variable that is passed as const
to a function does not have to be const
outside that scope.
Sure you can cast away constness using const_cast
but attempting to modify a const
object is undefined behavior and so it is no less immutable than constexpr
in that sense, from the draft C++11 standard section 7.1.6.1
The cv-qualifiers:
any attempt to modify a const object during its lifetime (3.8) results in undefined behavior
Jonathan Wakely notes that a constexpr variable like const variables can have a mutable member but that member can not be used in a constant expression.
Note that a constexpr variable is also const, from the draft C++11 standard section 7.1.5
The constexpr specifier:
A constexpr specifier used in an object declaration declares the
object as const.
const
dosn't ensure bitwise constness, e.g. as classes can have mutable members (typical example would be a private mutex for internal synchronization) and you can const_cast
away the constness from a pointer.
constexpr
declares a constant variable or function that can be calculated at compile time, which implies some restrictions on what the object can be, but I believe, the keyword itself doesn't provide any additional guarantees during runtime compared to const
.
See also this discussion.