Search code examples
c++const-char

casting away the constness using const_cast


No. This question in NOT duplicate of When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?

The question asked here is no ways similar to the link described as duplicate.

First question : I am using const_cast below for two cases. one of it works. the other doesn't.

1. int* const //Works.

In this syntax the address to which the variable would point to cannot be changed. So i used const_cast as below and it works:

`
int j=3;
int *k=&j;
int *m=&j;
int* const i=k; 
const_cast<int*>(i)=m; //OK: since i=m would not work so cast is necessary`

2. const int* //Doesn't work.

The address being pointed to can be changed however the value cannot be changed(though can be changed by making the variable point to different address). The const_cast i am using doesn't seem to work here:

`
int j=9;
int *k=&j;
const int* i1=0;
i1=k; //OK
//*i1=10;//ERROR.`

So i tried to typecast as below through various ways but nothing works:

const_cast<int*>(i1)=10;
const_cast<int*>(*i1)=l;
*i1=const_cast<int>(l);
*i1=const_cast<int*>(10);

Second question: Are all the casts available only for pointers and references? Is the following example not valid where no pointer or reference is in picture?

const int a=9;
int b=4;
const_cast<int>(a)=b; //cannot convert from 'int' to 'int'. why is compiler
                      //trying to convert from int to int anyways or fails         
                      //when both the types are same.

Solution

  • const_cast is applied to expressions, not objects, and itself is an expression as well:

    § 5.2.11 [expr.const.cast]/p1:

    The result of the expression const_cast<T>(v) is of type T. If T is an lvalue reference to object type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are performed on the expression v

    1. const_cast<int*>(i)=m;

    This call is invalid, because the left side of the assignment has a prvalue value-category, and an int* prvalue doesn't support an assignment. The correct syntax would be const_cast<int*&>(i)=m;, but since i in your example was declared const, it would invoke undefined behavior .

    1. const_cast<int*>(*i1)=l;

    Dereferencing a pointer of type int* creates an expression of an lvalue value-category, and because the cast expression is on the left side of the assignment, it should be a cast to an lvalue reference type, namely const_cast<int&>(*i1)=10; (provided that whatever i1 points to was not declared const).

    1. const_cast<int>(a)=b;

    The const_cast<int>(a) part itself is valid, in particular you can apply a const_cast to an expression representing an object which is not of a pointer type neither of a reference type. But since it's on the left side of the assigment it won't compile. And even if you change it to const_cast<int&>(a)=b; it will trigger undefined behavior, because a is declared const .


    § 7.1.6.1 [dcl.type.cv]/p4:

    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.