Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The C++ Standard, [dcl.type.cv], paragraph 4, states [ISO/IEC 14882-2014], states:

Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.

...

In this noncompliant code example, the function g() is passed a const int &, which is then cast to an int & and modified. Because the value referenced to was previously declared as const, the assignment operation results in undefined behavior.

Code Block
bgColor#FFcccc
langcpp
void g(const int &ci) {
  int &ir = const_cast<int &>(ci);
  ir = 42;
}

void f() {
  const int i = 4;
  g(i);
}

...

In this noncompliant code example, a const-qualified method is called, which attempts to cache results by casting away the const-qualifier of this. Because s was declared const, the mutation of CachedCalc results in undefined behavior.

Code Block
bgColor#FFcccc
langcpp
#include <iostream>
 
class S {
  int CachedCalc;
  
  int expensiveCompute() const;  
public:
  S() : CachedCalc(0) {}
  
  // ...  
  int Calculate() const {
    if (!CachedCalc) {
      const_cast<S *>(this)->CachedCalc = expensiveCompute();  
    }        
    return CachedCalc;
  }
};

void f() {
  const S s;
  std::cout << s.Calculate() << std::endl;
}

...

This compliant solution uses the mutable keyword when declaring CachedCalc, which allows it to be mutated within a const context without triggering undefined behavior:

Code Block
bgColor#ccccff
langcpp
#include <iostream>
 
class S {
  mutable int CachedCalc;
  
  int expensiveCompute() const;
public:
  S() : CachedCalc(0) {}
  
  // ...  
  int Calculate() const {
    if (!CachedCalc) {
      CachedCalc = expensiveCompute();  
    }        
    return CachedCalc;
  }
};

void f() {
  const S s;
  std::cout << s.Calculate() << std::endl;
}

...

In this noncompliant code example, the volatile value s has the volatile qualifier cast away, and an attempt is made to read the value within g(), resulting in undefined behavior.

Code Block
bgColor#FFcccc
langcpp
#include <iostream>

struct S {
  int i;
  
  S(int i) : i(i) {}
};

void g(S &s) {
  std::cout << s.i << std::endl;
}

void f() {
  volatile S s(12);
  g(const_cast<S &>(s));
}

...

[ISO/IEC 14882-2014]7.1.6.1, "The cv-qualifiers"
[Sutter 04]Item 94, "Avoid casting away const"

 

...