0

Hi i am trying to understand the explicit casting in C++, and so playing around by creating different examples. Below i am giving an example which i think should be illegal as it changes the value of a const object.

const char t='a';
const char *pc=&t;
char *p = const_cast<char*>(pc);
std::cout<<"Before changing t "<<*pc<<std::endl;
*p='c';
std::cout<<"After channging t: "<<*pc<<std::endl;

After executing the program the value of the object t successfully changes to c as i can see it in the console. My question are as follows:

  1. Shouldn't this be illegal since the whole point of having a const object is that it cannot be changed.
  2. What is the need of having this const_cast and it seems to me that it is dangerous in the sense that we are changing the const object.
  3. Is it perfectly okay to use const_cast like this?Again, if not then when should i use it?
Jason Liam
  • 465
  • 1
  • 14
  • 7
    It *is* illegal. If you rob someone and don't get caught, is the robbery legal? – molbdnilo Feb 12 '21 at 14:28
  • See for example [this question](https://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func) for a _valid_ use of `const_cast`. – churill Feb 12 '21 at 14:34
  • If you output the value of `t` rather than that of `*pc`, you might discover that its value actually didn't change. [Example](http://coliru.stacked-crooked.com/a/433a585979af30d7) – molbdnilo Feb 12 '21 at 14:35
  • Yup why is *pc is different than t when t is const? I also checked the case when t is a nonconst.In that case the value of t is actually changed unlike in the const case.I think this may be happening because of a creation of a temporary. – Jason Liam Feb 12 '21 at 14:38
  • @molbdnilo that might be misleading. Arguing about UB kind of meaningless as it depends on the compiler, architecture, … But if you check `t` if the value didn't change then it is likely not because the memory `pc` is pointing to (where `t` is located) didn't change, but because the compiler correctly assumed that the value won't change. – t.niese Feb 12 '21 at 14:45
  • @t.niese Or more generally: Because of UB. When there is UB, it is the explanation for everything about the observed behaviour :) – eerorika Feb 12 '21 at 14:47
  • C++ is not a nanny language. It gives the programmer enough rope to shoot themselves in the foot. You can do illegal things, which may appear to work as intended. Sometimes illegal things are *legal* as an extension on a particular vendor's compiler implementation — not so good for portability, but sometimes portability isn't a concern. The provided code example demonstrates lying to the compiler, which in turn leads to **undefined behavior**. The most insidious manifestation of undefined behavior is code that appears to work as desired. – Eljay Feb 12 '21 at 15:00
  • @eerorika Yes, I agree with that. The problem is just if you say to check if `t` changed, and the OP decides to don't do it with a `std::cout` after the UB happened, but e.g. with a debugger then you might - depending on the compiler, architecture, … - see that `t` changed and if you combine it with the `std::cout` of the `t` it is even more confusing. – t.niese Feb 12 '21 at 15:02
  • @t.niese In a way, something that adds confusion may actually be a useful step in learning what UB means :) – eerorika Feb 12 '21 at 15:03
  • 1
    The reason the compiler allows you to code undefined behavior (UB) with no diagnostic required (NDR) is because the general situation may be difficult to determine when the code stumbles into UB. Where "difficult" is on the level of "we haven't solved the halting problem yet". – Eljay Feb 12 '21 at 15:05

2 Answers2

3

Why is it Legal to Change a const value using const_cast in C++

Why do you assume that it is "Legal to Change a const value using const_cast in C++" and what do you mean by "Legal to Change"?

(†) The value of a const object cannot be changed. The behaviour of attempting to modify a const object is undefined.

  1. What is the need of having this const_cast

Sometimes you have a const reference to a non-const object, and you want to modify that non-const object. Those cases are rare, and thus it is rare to need const_cast.

Other times you have functions that accept pointer to non-const but will never modifies the pointed object. You can const_cast to call such function with a pointer to const. This case may be sometimes encountered when using ancient C libraries. Be very careful to not assume the "never modifies the pointed object" wrongly.

  1. Is it perfectly okay to use const_cast like this?

Undefined Behaviour (UB) is not perfectly OK. It is entirely bad. Don't do it.


why is *pc is different than t when t is const?

It may appear to be so, because the behaviour of the program is undefined.

So is it compiler dependent?

UB can depend on compiler. It can also depend on system libraries, number of CPU cores and the phase of the moon. There are no guarantees of behaviour being the same for any combination of any conditions. Nor are there guarantees for the behaviour to be different. There are no guarantees for the behaviour whatsoever.

whether we can change the value of const using const_cast?

See (†) above.

eerorika
  • 181,943
  • 10
  • 144
  • 256
0

Shouldn't this be illegal since the whole point of having a const object is that it cannot be changed.

C++ uses the term "Undefined Behavior". It is Undefined Behavior, because as you say, t is a const object.

What is the need of having this const_cast and it seems to me that it is dangerous in the sense that we are changing the const object.

It is intended for const variables that refer to non-const objects.

Consider this variation of your code.

char t='a'; // No longer a const char!
const char *pc=&t;
char *p = const_cast<char*>(pc);

Here, pc is a "pointer to const char", but it happens to be pointing to a char that isn't const.

In this situation, the code is valid. The character t may change, while the pointer pc can not be used to modify it.

Is it perfectly okay to use const_cast like this?

Not in the way you used it. See above.

Drew Dormann
  • 50,103
  • 11
  • 109
  • 162
  • I understood what you did, as i already checked that case(that you gave) beforehand.I know it is defined behavior in that case and const_cast is intended for that. But question is why not directly change the variable t if it is nonconst? We can just say t='c' instead of using const_cast. – Jason Liam Feb 12 '21 at 14:31
  • @JasonLiam `why not directly change the variable t if it is nonconst?` Because it is a simplified example. The intended assumption is that the context where the const_cast is used doesn't and cannot have access to `t`. – eerorika Feb 12 '21 at 14:33
  • @JasonLiam then you might be asking "Why did the compiler let me do this?", and not "Why is it legal?" Is that the case? – Drew Dormann Feb 12 '21 at 14:34
  • So is it compiler dependent, whether we can change the value of const using const_cast? – Jason Liam Feb 12 '21 at 14:49
  • @JasonLiam a few people have told you what it is already. I suspect you'll benefit from learning what undefined behavior means. Nobody can define for you how _undefined behavior_ will behave. – Drew Dormann Feb 12 '21 at 14:52