Comments

Back to the High Programmer's Blog

Back to the article

Alan De Smet at 21:18 Nov 12, 2006

Fscking spammers. You're wasting your time. 1: I use rel=nofollow, so you're not getting any Google PageRank for your spam. 2: I flag spam pretty quickly; I'm notified of new comments within a few minutes.

All that said, it's getting a little annoying flagging the spam, so I've added the World's Dumbest CAPTCHA. Inspired by Lawrence Lessig's blog, you just type the magic word (it's "human", for now), into the provided box. It's not great security, but hopefully it's enough. On the up side, it's really easy to implement and really easy to use (I hope. Sorry for the bother, blame the scum willing to piss all over the internet for short term gain.

Peter Keller at 22:31 Nov 14, 2006

If instead of the word "human", the word is random, and you don't tell us what the word is, I bet that'll cut down on the rest of the content free comments that might get posted.

Paul at 12:36 Jan 12, 2007

Excellent article. Just want to send some thanks for clearing that up. (sorry to hear about the spam, sucks)

Ram at 2:40 May 18, 2007

Good Article. Thanks for clarifying.

Christian at 3:38 Aug 3, 2007

Very helpful article: I just spend 3 days entangled in a debugging issue related to mutable and you have put in words what I had been sensing all the way. Thanks a lot!

Bob at 9:11 Aug 28, 2007

Thank you for making this subject clear by presenting clean examples. =)

Andrei MR at 10:32 Aug 29, 2007

Thanks for clarifying 'mutable.' It's nice to know that I continue to never need it. That C++ needs keywords like 'mutable' (like 'virtual') is evidence that C++ is a terrible language.

Alan De Smet at 17:44 Aug 29, 2007

"That C++ needs keywords like 'mutable' (like 'virtual') is evidence that C++ is a terrible language."

Utter nonsense. C++'s const and mutable are a powerful pair of features that allow greater enforcement of programming contracts. This post gives a good example of C++, thanks to const, being able to enforce a programming contract in a way that Java can't. (I've chosen Java because it's frequently regarded as being much better than C++. Admittedly I have no idea what languages you actually prefer over C++.) And once you have const, you'll need (however infrequently) mutable to handle the special cases where an object is logically constant, but for implementation reasons need to change.

Brooks Van Pelt at 5:06 Sep 20, 2007

Alan: I just read your posting, and these comments, and thought I'd add a pertinent comment. I often have to keep sets of data in memory, and typically package each "element of a set" (think struct !) as a class. Once its in a class its easy to store in a set; I just implement operator < so I know which members of the class form the "key" and which are associated data. This works nicely for me until I need to modify the class members which are not a part of the key (obviously I don't want to modify the key!). The compiler I use on our SUN machines here at work complain that I'm trying to modify a const object (the object member in the set). The VC++ compiler I ofter use for initial development doesn't complain about this. I can't decide which is worse: complaining about modifying a non-const member (the compiler can't tell which are key elements and which aren't !), or the lack of complaint (it will allow me to ruin the underlying b-tree structure by modifying a key-member? Sheesh!). I just battled through this this am, and ended up just putting the data into both sides of a map (I know! I know!). When I have a sec I'm going to explore "mutable" on the Sun side to see if it stops complaining. There's no hope for the VC++ side, as its allowing something it really shouldn't! Brooks

Matthew at 7:20 Dec 4, 2007

Nice article, I have seen the best use of mutable when dealing with classes designed to be thread-safe. Since many string and classes of the like (which are very mutable in C++ unlike Java and C#) don't handle being written to and read from at the same time very well, it is nice to have thread synchronization features of the OS to prevent corruption, problem is, without mutable... const functions can't manipulate these structures. To Andrei MR: Java does on the other hand have some point in making the class define the constness of an object rather than the methods, but it also limits the possibilities. Doesn't make either a better languages, just like C++ requires the nasty looking dynamic_cast when trying to reproduce even Java's one class multiple interfaces inheritance if both a base class and a implemented interface have the same base. Java can handle this with nicer looking code and probably better than C++.

Andrew Que at 9:55 Jan 23, 2008

Thanks for that article. I kept asking myself why someone would want the mutable keyword, since it just seemed like a bad idea. The pi example makes sense, although I still see very few places this keyword is a good practice.

Happy coding, A.A.Que

Kenneth Porter at 16:10 Mar 7, 2008

Shouldn't Employee::promote lack the const keyword?

Alan De Smet at 17:22 Mar 7, 2008

Kenneth: You are most certainly correct. Thanks for pointing it out. I've fixed it.

Richard Gomes at 6:07 Jun 7, 2008

Your article is very clarifying. I've put a reference to it in our website.

These articles may be of your interest: http://www.jquantlib.org/index.php/DesignType... http://www.jquantlib.org/index.php/Providing_...

Thanks a lot.

-- Richard

Mario Galindo at 16:19 Jul 4, 2008

The article is good. This topic is also very well explainded into the B.Strustrup book.

For the people that are saying that mutable makes C++ a bad language: "That C++ needs keywords like 'mutable' (like 'virtual') is evidence that C++ is a terrible language.", I want to expalin them that this is the oposite.

Mutable makes C++ a better language. Let me explain that:

An object saves two type of information: 1.- The logical information. For instance in the Employ object, it stores all the information thas has to be with an employ (name, telephone, etc.) 2.- The internal funcional information. This is memory that is stored into the object to make that the object work well into the program. For instance gc: garabage collector pointers, the pi number (good example), counters for debuger and others. All of this information do not have realition with the employ abstract idea. It is used to make the house keeping of the program.

Well, when you instruct that and object is constant, normally you are trying to keep constant the abstract idea of what is an employ but you don't have any problem if the internal house keeping information is changed. Without this change the gc will not function for example, or you can reallocate the object in other place of memory and this needs to change some internal pointers, intrusive list pointers, etc.

This is were the mutable keywords take place. When a programmer reads that a variable is mutable, he knows that this variable is not part of the abtract representation of an employ. On the contrary, he knows that this variable is beeing used to sustaint that object Employ into the program and this information can change for internal reasons without altering the employ information.

mutable was not necesary in the past becasu you can cast a memory to be not constant and then modify it. However, C++ has the mutable keyword because this makes the intention of the programmer more clear for the reader informing he that this memory is used only for internal functionality only. Don have nothig to do with the employ.

This makes C++ a better language! Because you can write preciselly what variables are part of the employ information (abstract idea) and what variables are for internal function only (how the object it is hose keept).

Regards.

LTrain at 10:45 Sep 15, 2008

Great analysis. I agree to using it sparingly. I would like to add one common usage for mutable that I have found. Mutexes. If I have a class and I want to call a Get method for a parameter, I want that method to be const because I would like to make sure a Get method does not modify any data in the class even non-const data. So I make the method const for protection, but if this class is used accross threads I want to use the mutex that is part of my class. Unfortunately because the method is const it will not let me lock the mutex that is a member variable for that instance. This is where you use mutable. Make the mutex mutable so that you can have the protection of the const and the thread-safeness the mutex provides.

class CTest
{
public:
    Test() : m_X(0) {};
	void SetX(const int x)
	{
		m_Mutex.lock();
		m_X = x;
		m_Mutex.unlock();
	}
        // Make const because we want to protect all member variables
	int GetX(void)const
	{
		int x;
		m_Mutex.lock();
		x = m_X;
		m_Mutex.unlock();
		return(x);
	}
private:
	int m_X;
	// Mutable to protect data in const methods.
	mutable CMutex m_Mutex;	
};

Rick at 22:01 Sep 22, 2008

Thank you so much for your post! Actually I had an idea for a multimedia project of mine that might just work.

It's a thread-safe, lock-free circular buffer for audio data (let's call it CircularBuffer). Since a read of the buffer alters the buffer's head (or tail, depending on your particular implementation), that variable is altered so i can't pass the buffer as "const".

However I want to impose a limit (or allow the user to impose it) such that a method which reads the circular buffer won't write data to it. By declaring the m_Head member variable as mutable, I can declare the Read() method as const, as follows:

class CircularBuffer {
public:
// ...
   int Read() const;
   void Write(int sample);
// ...
private:
// ...
   mutable int m_Head;
   int m_Tail;
};
This way I can do the following things:

class SomeClass {
   void ReadFromBuffer(const CircularBuffer* mybuffer);
};

This makes sure that SomeClass can read data from the circular buffer, but NOT write into to it!

Well, the class code compiles but I haven't really tested it since I'm rewriting other parts of the code. What do you think?

LTrain at 12:01 Sep 23, 2008

Rick, m_Head does not need to be mutable in your example. In fact it defeats the purpose of making int Read() const. You want read to be const and m_Head to be const in the read method. You want don't want m_Head to be const in the Write() method. This means your declaration of void Write(int sample) is correct and should not be const. By making m_Head mutable you can modify m_Head in both the Read method and the ReadFromBuffer() method, both are probably bad ideas. Generally you don't expect read methods to be able to modify anything.

You have to use some sort of sync method to make it thread safe. 1) use mutexes or semaphores 2) disable interrupts 3) Only allow one thread to modify the data by asking what thread you are on and then firing off a call-back if you are not running on the right thread.

Mutable does not get around any thread-safe issues.

nimble at 14:05 Sep 23, 2008

LTrain, while mutexes are a good use case for "mutable", your particular example does not actually require a mutex unless you're on a rather weird architecture where reading or writing an int is not an atomic operation.

Alan De Smet at 15:47 Sep 23, 2008

Rick: If I understand correctly, if I have "CircularBuffer cb;" and I repeatedly call "cb.Read();", I should expect to get a different answer each time. The CircularBuffer behaves differently after each call to Read. That doesn't sound like a const operation to me. As such, I don't think the combination of const and mutable is the right solution.

Just off the top of my head, you might use inheritance to provide a read-only interface.

class CircularBufferReadOnly {
public:
   virtual int Read() = 0;
};

class CircularBuffer { public: // ... int Read(); void Write(int sample); // ... private: // ... int m_Head; int m_Tail; };

class SomeClass { void ReadFromBuffer(CircularBufferReadOnly & mybuffer); };

I've made Read pure virtual in the CircularBufferReadOnly on the assumption that it's only meaningful to have a CircularBuffer, not a ReadOnly one. In Java you'd accomplish the same thing with an interface. If my assumption is wrong, there is no reason you can't implement it there.

(As an added bonus, this thread has revealed a bug in my comment formatting code, doubling the number of blank lines. I'll have to look into that.)

LTrain at 8:12 Sep 29, 2008

nimble you are completely correct. That was just for an example. Although if x was not an int and was a large struct or some large object then the reads and write would be done by the compiler inserting a call to _memcpy() behind the scenes or even a call to an implicit or explicit copy constructor. This means to read or write more than one word it will take multiple cycles. In that case you would not want to do a read half way through a write and get inconsistent data. The code above was to demonstrate the concept.

Imbecil at 9:29 Nov 18, 2008

@Brooks Van Pelt:

The SGI doc at the SGI website states that "In Simple Associative Containers, where the elements are the keys, the elements are completely immutable; the nested types iterator and const_iterator are therefore the same." (http://www.sgi.com/tech/stl/AssociativeContai...)

Scott Meyers disagrees with this in his "Effective STL" book (Item 22). He states that the parts of elements in a set (but not in a map) that do not affect the ordering can be changed.

I'd rather trust the dudes that programmed the STL (such as Matt Austern) over the above mentioned book.

I think that you might want to use a "map" instead of a "set" for your purposes. I think that's the whole idea about "map" - to separate the key from the other-parts-of-the-value-that-do-not-affect-ordering.

Alan De Smet at 20:36 Dec 2, 2008

In my post several up, I neglected to have CircularBuffer inherent publically from CircularBufferReadOnly. This makes my post a bit nonsensical. My apologies.

Mick at 20:24 Apr 15, 2009

I hate to necro-comment this blog, but it's pretty high up on Google's radar for "mutable keyword" and I just learned the common definition (and apparently the conception of mutable) is very off base... and I'm personally fairly put off and need to vent / ask questions.

MSVC defines mutable as (This keyword can only be applied to non-static and non-const data members of a class. If a data member is declared mutable, then it is legal to assign a value to this data member from a const member function)

I haven't tried to find formal specs, but this is incredibly misleading. It is also what I always assumed mutable does. ie. "it is legal to assign a value to this data member from a const member function"

Instead the MSVC compiler lets anything (with access privileges) at anytime assign a value to a mutable member (of a const object)

Ever sense I've been using mutable I've been assuming the member for a const object could only be changed from inside the object's const member functions.

Not so. I'm bummed. Anyone know what the spec says, or just off the top of your head if other compilers treat mutable differently (doubtful) from MSVC?

PS: This means mutable is useless outside of private/protected members... which really tend to just make internal code really circuitous. I hope future specs could remedy this.

Mick at 0:01 Apr 16, 2009

For the record, I've sent an email to the standards secretary:

--------------------------------------------

I discovered the mutable keyword only a couple years ago, and used it only in some particular situations, for purposes which I thought left objects to be readonly (ie. const)

Though I don't believe the formal specifications for standard C++ are readily/freely available online, most resources seem to describle the keyword something like this...

"This keyword can only be applied to non-static and non-const data members of a class. If a data member is declared mutable, then it is legal to assign a value to this data member from a const member function." (taken from MSVC documentation)

I read this, and thought groovy... now I can pass an object as readonly, but still have some option of modifying some members during const member function calls. This I believe is how the mutable keyword SHOULD work (let us pray)

However I discovered today, that my objects passed as const are actually not safe. Call me daft or whatever for not noticing before (no one called me on it ever) but I learned after considerable investment in this keyword, that members declared as mutable in fact can be altered at anytime by anything (barring access declarations)

This is a nightmare, ney a travesty. Why is it an object apparently const, should contain non-const members. Any foreign const function can modify my mutable members (which are probably very important internal variables) ...and if not maliciously, on accident. Would it not make a world more sense to limit the modification of mutable variables for const objects to their own const member functions?

Please find a pertinent argument for me, and please consider changing the function of the mutable keyword in future C++ specifications (with oldstyle back compatibility via compiler options or other inline directives)

sincerely,

A concerned programmer in crisis

Jason at 16:06 Apr 28, 2009

Mick,

you can get all kinds of side effects of C++ features, if you are not careful with those. That includes implicit virtual functions, non-trivial constructors (constructors that are not "explicit") causing implicit conversions, even overload resolution, etc. The only way to get it right is to get it right, which usually happens if you experience it yourself or hear somebody else's experiences.

The mutable keyword has its own use. If you think it's dangerous, don't use. Many software companies don't use templates, because they think it's easy to use them wrong (by abusive programmers). Similarly, some don't ban multiple inheritance completely.

Rajendra at 4:21 Jul 20, 2009

@Mario : Nice comment - it's definitely about enforcing the right discipline in development teams.

Mutability should be concealed in implementation of the class by having const [public] member function(s) modifying mutable variables

Andre at 14:16 Jan 23, 2010

@Jason: I think Mick's complain is not only about the fact that mutable does what it does, but about the lack of documentation thereof. The latter complain has merits I think.

John Colman at 11:37 Apr 1, 2010

To me the original article proves that the author does not live or work in the real world.

Const correctness is highly desirable, but in the real world we often inherit (in the physical sense) interfaces and legacy code for which are are rarely permitted to meddle.

As some other commentators have alluded, mutable is sometimes necessary to store internal states and housekeeping values when programming to an imutable interface.

A good example is ostream. Ostream may not be used as a const as it itself requires internal state management. So I might use an ostream as a mutable member of a const class if I was forced to.

Other examples include counters, iterators and states used exclusively internally.

All I can say is thank god for mutable.

Doug at 20:30 Nov 24, 2010

For the simulation framework I maintain, there is only one place where the use of mutable makes sense - that is in the area of reference counting. Our base "Object" maintains 2 private data items to maintain a semaphore to provide multi-thread access to a memory management (i.e., reference counting). Out of all the code in the framework, for these two data elements, mutable makes great sense - I'm not messing with object "state" or content. I agree with the entire article.

d at 4:08 Feb 9, 2011

So, the keyword mutable means "read only access are promoted to read write access." The keyword const means "read only access". Think of a read-only SMB or NFS access to a filesystem that is mounted read-write and is repeatedly modified by something else.

Now, is there a keyword in C++ which stands for "read only access giving constant results that can be cached" ? Think of an immutable storage, as a CDROM.

d at 1:04 Feb 10, 2011

To illustrate the keyword mutable, think of a "nfs client kernel module" which, even in the case of read-only access, does stealthy things as collecting statistics and/or reordering read requests.

So, to abbreviate:

const means read-only.

mutable means stealthy.

I want a keyword which means constant.

Zemyla at 12:52 Sep 9, 2011

There's a data structure that requires mutable. It is the disjoint-set data structure. The pseudocode for the find() method goes like this:

function Find(x)
     if x.parent == x
        return x
     else
        x.parent := Find(x.parent)
        return x.parent

x.parent is being modified in the find() method, even though the object is logically the same as before the method is called. Thus, x.parent would need to be declared as mutable.

test at 2:57 Oct 25, 2011

test

gl at 13:11 Oct 28, 2011

Good article thanks. I've never needed mutable and it bugged me that I didn't quite understand it, but your examples cleared that up nicely.

Unca Alby at 21:18 Oct 19, 2012

I can think of a REALLY GOOD USE for the keyword, "mutable".

It is on a Job Interview Question.

Before that, I'd never heard of it, can't think of any time I'd use it. Thus my Web search, leading me here. Great article, btw.

Otherwise, I'm inclined to agree with the idea that, if you want it to be constant, declare it as such, otherwise don't. Simple.

precision at 22:49 Oct 24, 2012

thanx for d article.great help.at least from somewhere am i gettin the true concept. Jst those examples (program codes) were a bit high for my level cant they be somwhat simpler

Bill at 7:01 Dec 21, 2012

when you marked the data member _name as const and encapsulate that, then you lost some future functionality (e.g., setname() ). and the code may not be as reusable for another project. as you say, if the object is instantiated as const, nothing can be changed, unless explicitly marked mutable. for a non-critical data member, this may be exactly what the programmer desires. if you code the data-member as const, well that's what you get, no matter how you instantiate the object. it just depends what you want to do.

Bill at 7:01 Dec 21, 2012

when you marked the data member _name as const and encapsulate that, then you lost some future functionality (e.g., setname() ). and the code may not be as reusable for another project. as you say, if the object is instantiated as const, nothing can be changed, unless explicitly marked mutable. for a non-critical data member, this may be exactly what the programmer desires. if you code the data-member as const, well that's what you get, no matter how you instantiate the object. it just depends what you want to do.

aao at 8:12 Jan 25, 2013

I appreciate your up to the point article. Noobs usually abuse mutable , or the think it is an "interview question", somebody putting it down for them is very nice

aao at 8:29 Jan 25, 2013

I appreciate your up to the point article. Noobs usually abuse mutable , or the think it is an "interview question", somebody putting it down for them is very nice

Eovento at 18:23 Oct 29, 2013

Many thanks for the great article!

bhaylu at 1:32 Sep 12, 2014

Why you says following use of mutable is incorrect & defeats purpose of const in C++?

const Employee john("JOHN","007",5000.0); .... .... john.promote(20000.0);

Please explain more about this

Alan at 21:01 Sep 14, 2014

Bhaylu, if you're promoting john, you're changing his state. If you're changing his state, you're not treating him as constant and you shouldn't have declared him such.

Joshua Kronengold at 11:23 Feb 18, 2015

Nice points. Enforcement of const is all the more important with massive threading and multiprocessor architectures being the direction computer programming is going these days.

You missed a spam posted on 6:07 Jun 7, 2008, I think.

Thomas at 0:29 Feb 10, 2016

Good overview on the "old" meaning of const + mutable until C++11. (Starting with C++11 const => thread safe; see e. g. Herb Sutter's posting + Video on Sutter’s Mill. So you should think more than twice before you use mutable to implement caching or some kind of lazy algorithm as part of a const method.)

Regards,

Thomas

Post Message

Your name:
The word "human": (To fight comment spam you must enter the word "human" in this box.)
Your web site: (optional)
Your email address: (optional)
(Your email address is not displayed to others nor stored. It is only used to display a Gravatar Avatar.)



Supported tags: [B]Bold text[/B]   [I]Italic text[/I]   [TT]Typewriter font[/TT]   [CODE]Preformatted text[/CODE]   [QUOTE]Block quote[/QUOTE]   [QUOTE="Original Author"]Block quote[/QUOTE]   [URL="http://www.example.com"]Example Corporation[/URL]