12

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?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Vector
  • 10,879
  • 12
  • 61
  • 101
  • Related to [“Constant expressions” prior to C++11](http://stackoverflow.com/q/26024942/1708801) – Shafik Yaghmour Dec 01 '14 at 04:57
  • 1
    I can't find my copy of the book to check the context, but since constexpr still does not guarantee immutability I would be surprised if that's what he's suggesting. From your short quote it looks to me like he's just saying immutability is important, not that constexpr is better for achieving that than const, or vice versa. – Jonathan Wakely Dec 01 '14 at 10:48
  • @JonathanWakely - Perhaps you are right, it's just thrown in there since the general subject is what he calls _immutability_. I am putting the whole paragraph up there now - it is a summation of the material on `constexpr`,so I understood there was something special about `constexpr`, like the other points mentioned there, but maybe not. – Vector Dec 01 '14 at 12:17
  • @JonathanWakely I think what makes it ambiguous is the way the sections are cited in specific statements, they seem to imply what the OP is asking about. I agree I don't believe he is suggesting that either but after reading it several times it is not the most clear statement even with the whole context. – Shafik Yaghmour Dec 01 '14 at 13:12

2 Answers2

11

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.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • _He clearly states in the beginning of the section.._ Yes, understood. That's all part of the question: How do you modify the value of `myConst` in the declaration: `const int myConst=999`? The compiler enforces `const`. Maybe by subverting it with a pointer? Would that be impossible with `constexpr`? Is there something "more immutable" about `constexpr` I'm not sure I understand this answer, except in the case of variable passed as `const` into functions so they can't be modified in the function. – Vector Dec 01 '14 at 07:03
  • 1
    _"an object that is const is immutable in that scope but may not be const in the larger scope"_ technically an object is either const or not, period. A non-const object might be used through a "const access path" (e.g. through a const pointer), but the object itself is still non-const. And immutable doesn't just mean "doesn't change right now, but might change later". – Jonathan Wakely Dec 01 '14 at 10:10
  • @JonathanWakely that is what I get for writing that before I go to sleep, fixed. – Shafik Yaghmour Dec 01 '14 at 10:19
  • As MikeMB's answer shows, a variable declared constexpr can still have mutable members, so is not truly a compile-time constant. – Jonathan Wakely Dec 01 '14 at 10:47
  • @JonathanWakely that is an interesting edge case, I reworded to be less absolute on that point. – Shafik Yaghmour Dec 01 '14 at 13:55
5

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.

MikeMB
  • 20,029
  • 9
  • 57
  • 102
  • 1
    An object declared with constexpr can still have mutable members, even after the resolution of the issue Richard Smith raised ([DR 1405](http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1405)) it just can't be used in a constant expression. So you're right that means constexpr still doesn't guarantee immutability. And you can `const_cast` away the constness of something declared `constexpr` (but trying to modify it is still undefined, just like a variable declared `const`) – Jonathan Wakely Dec 01 '14 at 10:27
  • Thats what I meant with "the keyword itself doesn't provide any additional guarantees during runtime compared to const". Do you want to say, I should remove the link?. I added it, because it was the first source I found, which explicitly stated that `constexpr` objects can have mutable members, thus supporting my point of "`constexpr` not beeing more constant than `const`" – MikeMB Dec 01 '14 at 10:32
  • I think it's useful to keep it – Jonathan Wakely Dec 01 '14 at 10:35
  • What remains unclear to me is, whether your comment was meant to support or correct my answer. – MikeMB Dec 01 '14 at 11:26
  • I was trying to support it with extra detail ... but you're right I wasn't very clear, sorry! – Jonathan Wakely Dec 01 '14 at 12:25