15

When the mutable specifier is used in the declaration of a non-static data member, the data is mutable no matter whether the rest of the object is treated as const. With this fact, we may easily have the impression that mutable specifier is the same kind of thing as the const qualifier, which turns out to be not true. In fact, the language classifies mutable specifier as a storage class specifier. This is quite counter-intuitive because mutable does not specifies storage duration.

What are the rationales behind this design decision?

What would make it less logical than it would seemed if mutable was a qualifier?

What are the advantages of making it a storage class specifier?

  • Your question is directly answered in [dcl.stc] of N4140: `The mutable specifier on a class data member nullifies a const specifier applied to the containing class object and permits modification of the mutable class member even though the rest of the object is const (7.1.6.1).` – uh oh somebody needs a pupper May 08 '16 at 06:16
  • 2
    `const` and `volatile` are part of the type. `mutable` isn't. – T.C. May 08 '16 at 06:18
  • 1
    An implementation is permitted to put a const object in read only memory - but not the mutable members, obviously. So if you squint a bit it is not totally unrelated to storage. – Alan Stokes May 08 '16 at 08:01
  • @user6292850 No, it does not, utterly not. –  May 08 '16 at 08:17
  • `const` applies differently to each 'level' when there is indirection in the type, but `mutable` is always "top-level". And it's nice to allow `mutable int *p;` instead of requiring `int * mutable p;` – M.M May 08 '16 at 13:50

1 Answers1

11

cv-qualifiers modify/restrict the object's semantics; mutable does not. It being part of the type would be superfluous in practically all scenarios, while necessitating more paragraphs about pointer conversions etc.

Thus it was decided to make it a decl-specifier that isn't a type-specifier. Since const can cause an object to be put into write-protected memory, mutable can cause an object not to be put into such storage, suggesting it is a storage-class-specifier.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • I suppose a hypothetical `mutable int C::*` (with `mutable` being part of the type pointed to) could be used to change a `const C` object's mutable `int` subobject via the pointer-to-member syntax, but certainly the cost is far greater than the benefit. – T.C. May 09 '16 at 19:01