0

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?

Community
  • 1
  • 1
Shadi
  • 1,701
  • 2
  • 14
  • 27
  • 1
    *"`a` in `int a = 1` is a constant expression that is processed at compile-time."* - Nope. No such guarantees in C++. Only `constexpr` variables provides such guarantees. – WhiZTiM Apr 10 '17 at 12:50
  • @WhiZTiM Unless you are cynical and read the implementation defined limit on complexity that a `constexpr` can have to be 0 and therefore `constexpr` is worthless. – nwp Apr 10 '17 at 12:58
  • No, not "may result in undefined behaviour" -- "**has** undefined behaviour". – Kerrek SB Apr 10 '17 at 13:00
  • 1
    @WhiZTiM: `const int a = 1` makes `a` a compile-time integral constant expression and has done so long before there was such a thing as `constexpr`. – Ben Voigt Mar 09 '23 at 18:13
  • @BenVoigt, you are right. Thanks for the correction – WhiZTiM Apr 18 '23 at 12:16

2 Answers2

5

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);
}
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
3

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.

nwp
  • 9,623
  • 5
  • 38
  • 68
  • both are working fine. unless you mean it is illegal even the expected results is correct. in this case, the second code in the question is illegal too. However, I have read somewhere, it is fine. what is not OK is `int a=1` then `f(a)`. what do you think? – Shadi Apr 10 '17 at 14:54
  • @Shadi You can get unlucky and the compiler decides to do what you want, but according to the standard it is undefined behavior and changing compilers or compiler optimizations may break the code. I don't know what second code in the question you are referring to. – nwp Apr 10 '17 at 15:13