Home > Blogs > More About mutable

More About mutable

By  Sep 20, 2008

Topics: Programming, C/C++

This post answers a question posted as a comment to Tip #29 use the mutable storage type to hide implementation details."Would using const_cast to achieve the same effect just be another way to skin a cat, or would there be any other important differences that I may be missing?"
I'm answering this question in a separate thread because replies can't use HTML tags.

Seemingly, mutable is just a convenience feature that is meant to rid the programmer from using const_cast so you could say that it’s nothing more than const_cast in disguise. In reality, it isn't. There are two reasons why I think mutable has an added value compared to brute force const_cast.
First, many programmers would avoid const_cast at all costs, which means that they would give up the const in the member function declaration if they didn't have mutable. I haven't checked the statistics but I have the impression that there were fewer const member functions in general in C++ before the advent of mutable.
Second, there's a more sinister aspect of const_cast. This operator is dangerous because it cannot distinguish between truly const objects that are being unconsted and non-const objects that were implicitly converted to const. I'll give an example of both:

#include <iostream>
using namespace std;

void func(const int & num)

int main()
 int n=0;
 func(n); //#1 non-const object implicitly converted to const
 cout<<n<<endl; //6
 const int m=0; //"real" const
 func(m); //#2 undefined behavior
 cout<<m<<endl; //surprise!

In the first func() call, a non-const object is implicitly converted to const, and then its const qualifier is being removed so that a new value can be assigned to it. This const_cast, however ugly, is safe because the object n isn't truly const.

By contrast, in the second func() call the argument is a true const object, which means that the implementation may have stored it in the ROM for example. Using const_cast to modify such an object is undefined, but the programmer const_cast cannot distinguish between these two scenarios. Now assume that the variables n and m are data members of a const object. Declaring these mutable guarantees that undefined behavior such as #2 shall not occur.