Reputation: 1771
I searched the Internet and the StackOverflow about the const_cast<> and the confusion it causes, I found useful things, however I still has a question.
Considering this code,
#include <iostream>
using namespace std;
int main(void)
{
const int a = 1;
int *p = const_cast<int*>(&a);
*p = 2;
cout << "value a="<< a << endl;
cout << "value *p=" <<*p << endl;
cout << "address a=" <<&a << endl;
cout << "address p=" <<p << endl;
}
The output is:
value a=1
value *p=2
address a=0x69fef8
address p=0x69fef8
I found that such code may result in undefined behavior. (for example the compiler may replace all the a
's with 1
's to optimize, and hence the cast has no meaning)
I also found this quote:
If you cast away the constness of an object that has been explicitly declared as const, and attempt to modify it, the results are undefined.
However, if you cast away the constness of an object that has not been explicitly declared as const, you can modify it safely.
and this:
Note that C++ provides
const_cast
to remove or add constness to a variable. But, while removing constness it should be used to remove constness off a reference/pointer to something that was not originally constant.
Now, considering the following modification on the code above:
int b = 1;
const int a = b;
the output is:
value a=2
value *p=2
address a=0x69fef4
address p=0x69fef4
I understand that:
a
in int a = 1
is a constant expression that is processed at compile-time.
a
in int a = b
is not and it can only be processed at run-time.
as described here.
My questions:
When is the const declaration explicit, and when is it not? and how could it be originally non-const?
Upvotes: 0
Views: 360
Reputation: 272467
A simple counterexample which is valid:
void foo(const int *a) { // Pointer-to-const here
int *p = const_cast<int*>(a);
*p = 2;
}
int main() {
int a = 1; // But underlying object is not const
foo(&a);
}
Upvotes: 5
Reputation: 9991
In this example:
int b = 1;
const int a = b;
a
is top level const
while b
is not.
If you were to pass them to a function like this:
void f(const int &i){
const_cast<int &>(i)++;
}
then f(a)
is illegal because you are changing a top-level const
object, an object that was declared as const
from the beginning, and thus your program will exhibit undefined behavior.
On the other hand, f(b)
will be fine, because b
started out as not const
, then got a const
added to it via the parameter conversion, and then got the const
removed again. Since b
started out modifiable you may modify it by removing a const
that was added.
Upvotes: 3