Shadi
Shadi

Reputation: 1771

c++ when the const is not an explicit one?

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

Answers (2)

Oliver Charlesworth
Oliver Charlesworth

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

nwp
nwp

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

Related Questions