-3

I tried executing the following program.

#include<iostream>
using namespace std;
int main()
{
const int a = 0;
cout << &a <<endl;
int* ptr = const_cast<int*>(&a);
*ptr = 2;
cout << ptr <<endl;
cout << *ptr <<endl;
cout << a <<endl;
return 0;
}

The output was:

   0xbf92ebd8
   0xbf92ebd8
   2
   0

From what I know, const_cast makes a mutable, so that, it can be changed. The change is reflected when I display *ptr, but the change is not reflected in a. Can anyone explain ?

EDIT: Thanks for all the answers. I get it that I am observing an undefined behavior. And, I was initially confusing between mutable and *const_cast*. But then, could you tell me for what all scenarios, do we use const_cast?

user1414696
  • 307
  • 4
  • 15
  • 1
    AFAIR, modifying const variables is considered an undefined behavior. You may expect anything to happen. – Spook Jun 25 '13 at 06:19
  • 5
    It is undefined behaviour. `a` is really const, so you can't cast away the constness without invoking UB. – juanchopanza Jun 25 '13 at 06:19
  • 1
    The compiler would most likely optimise all instances of `a` to the actual value. – Jonathan Potter Jun 25 '13 at 06:20
  • And this is what happened in my opinion: the compiler knows that `const`s don't/can't change value, so it optimized `cout << a` into `cout << 0`. But then it realized that the address of the variable was taken using `&a` and it needed to allocate memory for it, so it allocated some, returned its address which was assigned to `p`, then `*p`, when dereferenced, was changed in memory. –  Jun 25 '13 at 06:22
  • 2
    "From what I know, const_cast makes a mutable" -- No, that's what you *believe*, but your belief is not well grounded ... in fact, it's erroneous. – Jim Balter Jun 25 '13 at 06:29
  • 1
    `const_cast` may _well_ make `*ptr` mutable but it in no way has that effect on `a`. – paxdiablo Jun 25 '13 at 06:30
  • @ Jim Balter: Okay, I got that I was wrong here. The thing about const object becoming mutable is carried out by the 'mutable' keyword. But, for what all scenarios do we use const_cast? I can think of only one: There is function say *Add(const int& a)*, and I have an integer b, which is non-constant. If I have to pass *b* in this function, I pass it using const_cast. Can you point out more? – user1414696 Jun 25 '13 at 06:46

2 Answers2

4

From C++03 5.2.1 const_cast /7:

[Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer to data member resulting from a const_cast that casts away a const-qualifier may produce undefined behavior (7.1.5.1). ]

In 7.1.5.1 The cv-qualifiers /4:

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

And, in the terms and definitions section:

[Note: permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

Minor changes have been made in the latest standard but the general idea still holds. Bottom line, don't do that.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
1

C++11 Standard says:

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

That means, that you cannot expect anything, when attempting to do this. It may work, it may not, exception may be thrown, program may be terminated, depending on how designers of your compiler designed it.

Spook
  • 25,318
  • 18
  • 90
  • 167