Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const_cast VS mutable ? any difference?

From my understanding , mutable cancels the constness of a variable

Class A {
  void foo() const {
  m_a = 5;
}
mutable int m_a;
};

But also const_cast :

void print (char * str)
{
  cout << str << endl;
}

int main () {
  const char * c = "this is a line";
  print ( const_cast<char *> (c) );
  return 0;
}

So , what changes one from the other ?

Thanks

like image 210
JAN Avatar asked Jul 12 '12 18:07

JAN


People also ask

What is the point of const_cast?

const_cast is one of the type casting operators. It is used to change the constant value of any object or we can say it is used to remove the constant nature of any object. const_cast can be used in programs that have any object with some constant value which need to be changed occasionally at some point.

Is const_cast safe?

const_cast is safe only if you're casting a variable that was originally non- const . For example, if you have a function that takes a parameter of a const char * , and you pass in a modifiable char * , it's safe to const_cast that parameter back to a char * and modify it.

Is const_cast undefined behavior?

Even though const_cast may remove constness or volatility from any pointer or reference, using the resulting pointer or reference to write to an object that was declared const or to access an object that was declared volatile invokes undefined behavior. So yes, modifying constant variables is undefined behavior.

What is a mutable member?

Mutable data members are those members whose values can be changed in runtime even if the object is of constant type. It is just opposite to constant. Sometimes logic required to use only one or two data member as a variable and another one as a constant to handle the data.


3 Answers

const_cast cannot cancel constness of an object. const_cast can only remove constness from an access path to an object. Access path is a pointer or a reference to an object. Removing the constness from the access path has absolutely no effect on the object itself. Even if you use const_cast to remove the constness of the access path, that still does not necessarily give you the permission to modify the object. Whether you can do it or not still depends on the object itself. If it is const, you are not allowed to modify it and any attempts to do so will result in undefined behavior.

For example, this illustrates the intended use of const_cast

  int i = 5; // non-constant object
  const int *p = &i; // `p` is a const access path to `i`

  // Since we know that `i` is not a const, we can remove constness...
  int *q = const_cast<int *>(p);
  // ... and legally modify `i`
  *q = 10;
  // Now `i` is 10

The only reason the above is legal and valid is the fact that i is actually a non-constant object, and we know about it.

If the original object was really constant, then the above code would produce undefined behavior:

  const int j = 5; // constant object
  const int *p = &j; // `p` is a const access path to `j`

  int *q = const_cast<int *>(p); // `q` is a non-const access path to `j`
  *q = 10; // UNDEFINED BEHAVIOR !!!

C++ language does not allow you to modify constant objects and const_cast is completely powerless here, regardless of how you use it.

mutable is a completely different thing. mutable creates a data filed that can be legally modified even if the containing object is declared const. In that sense mutable does allow you to modify [some designated parts of] constant objects. const_cast, on the other hand, can't do anything like that.

like image 74
AnT Avatar answered Oct 22 '22 12:10

AnT


The difference is that const_cast can't cheat, but mutable is an exception to the rules.

On the first snippet m_a is mutable, and thus an exception to the rule that you can't modify data members on const member functions.

On the second snippet, const_cast tries to cheat, but really can't: while the type has changed, actual modification is not allowed: the string is truly const. Attempting to modify it would cause the program to exhibit undefined behaviour.

like image 35
R. Martinho Fernandes Avatar answered Oct 22 '22 13:10

R. Martinho Fernandes


The difference is semantic - i. e. same generated code, same run-time results (constness is a purely compile-time construct anyway), but the two constructs convey a slightly different meaning.

The idea is that you use mutable for variables that are in the class, but don't constitute the state of the object. The classic example is the current position in a blob object. Navigating in the blob does not count as "modifying" the blob in a way that matters. By using mutable, you're saying "this variable may change, but the object is still the same". You're stating that for this particular class, const-ness does not mean "all variables are frozen".

const_cast, on the other way, means that you're violating existing const correctness and hope to get away with it. Probably because you're working with a 3rd party API that does not respect const (e. g. an old school C-based one).

like image 27
Seva Alekseyev Avatar answered Oct 22 '22 12:10

Seva Alekseyev