Curious about mutable data member and inspector function

Started by
7 comments, last by adder_noir 13 years, 5 months ago
Hi,

I'm working through a link at the moment the C++ FAQ which is I believe from www.parashift.com. I'm come across an interesting concept which surprised me.

When defining an inspector function the author states that sometimes even an inspector function can alter a data member. I understand that to do this you must put the keyword 'mutable' before the data member's declaration.

The authoer does stuff like this:

#include <iostream>class Set{    public:    void myinspector(Set const* sp) const    {        Set* self = const_cast<Set*>(sp);        self->myint = 5;        std::cout << "myinspector has run and the value of myint = " << myint << std::endl;    }    int myint;};int main(){    Set mySet;    Set const* sp;    sp = &mySet;    sp->myinspector(sp);    return 1;}


I'll be honest, I wrote this code. There was no full example shown in the text so I absorbed the concepts and wrote this for myself. It appears that if you use const_cast within an inspector function you can cast a pointer passed as an argument to that function to a non-const pointer to that class and then change a data member (not marked as mutable) within that class.

My question is/are:

1)Why would you ever want to use 'mutable' anyway?

2)Although I'm very glad of the exercise and chance to grow my skills, why has the author shown this hack method of getting around using the 'mutable' keyword with a 'const_cast' inside the inspector function?

Many thanks for any help/insight offered ;o)
Advertisement
1) mutable is generally used for caching information. For example, a string class may not recalculate the hash code every time it's modified but might store it once it is asked for it.

2) If you are indeed talking about the C++ FAQ on parashift, then the author clearly states before showing the const_cast code "If your compiler doesn't support the mutable keyword".
Quote:Original post by adder_noir
1)Why would you ever want to use 'mutable' anyway?

You wouldn't. It's a way to deliberately design around deliberately broken design. There are so many subtle issues related to const-ness, but most compilers do not report them. Using something like PCLint however does.

I don't think I've ever seen mutable used in actual code. Ever. I don't think most people even know it exists.

Quote:2)Although I'm very glad of the exercise and chance to grow my skills, why has the author shown this hack method of getting around using the 'mutable' keyword with a 'const_cast' inside the inspector function?

They like undefined behavior.

If something is const, compiler is free to assume it will not change. So violating that means just about anything can happen. There was an post here a while back where precisely this type of problems arose.

const_cast should simply never be used. If it does, it's an indication of broken design.
Quote:Original post by Antheus
They like undefined behavior.

If something is const, compiler is free to assume it will not change. So violating that means just about anything can happen. There was an post here a while back where precisely this type of problems arose.
I disagree -- doesn't the compiler have to take aliasing into account, meaning it can almost never assume that const things don't change?
e.g. A conformant compiler will fail this assertion, whereas one making that assumption may not:
void TimesTwo( const int* input, int* output ){  int first = *input;  *output = first * 2;  int second = *input;  assert( first == second );//oops, our const input just changed}int main(){  int i = 42;  TimesTwo( &i, &i );}
Quote:const_cast should simply never be used. If it does, it's an indication of broken design.
That's still true though!
OK great so really I can just reflect on this as a good academic exercise without having to worry too much about ever meeting stuff like this in the real world then?

THanks to all who posted ;o)
Quote:Original post by adder_noir
OK great so really I can just reflect on this as a good academic exercise without having to worry too much about ever meeting stuff like this in the real world then?

THanks to all who posted ;o)


I wouldn't go that far. SiCrane is right on the money as to why they are used. Mutable is extremely useful for class methods that are conceptually const but cache some internal state. Mutable and const_cast don't necessarily indicate a broken design at all. IMO, that's only an impression that people have caused by the fact that many programmers don't have any clue why or when they should be used, and therefore end up using them in hackish or incorrect ways.

Also, even when the compiler supports the mutable keyword, const_cast is still useful for getting a non const pointer to this inside a const method. Obviously that is wide open to abuse, but it can be used correctly.

[Edited by - 1863 on October 22, 2010 2:04:09 PM]
I find myself using mutable all the time on objects that might be accessed from multiple threads.
mutable boost::mutex mutex;

I found to be somewhat common in my code.
Code that uses mutable does appear in the real life. You've probably used code that uses mutable without ever noticing. Quite a few boost classes use mutable data members, as do a couple of MSVC's standard library classes, like std::streambuf as well as a few classes in libstdc++ for GCC. On the other hand, mutable is uncommon enough that there's a long standing const-correctness bug involving mutable in MSVC that's been around since at least MSVC 2003 that I'm the only one who's ever submitted a bug report for. For the most part the only way you'll ever notice that code uses mutable is if there's a bug involved (either in the code or the compiler), so if you're working with good code you'll almost never notice it.

On the other hand, there's pretty much just about only one legitimate use for const_cast: interfacing with libraries that don't properly put const on their interface methods. For example, there are a couple of Python extending and embedding C API functions that take char *'s for string arguments even though they don't modify the strings. So the presence of a const_cast is an indication that someone did something wrong - either you in your code or someone else in the code that you're interfacing with.
Ok guys thanks for the replies ;o)

This topic is closed to new replies.

Advertisement