0

When I tried below code I got strange results.I am trying to change value of constant by using the pointers.But when I output the results pointer value and the original variable variable value its giving two different values.Can anyone explain what exactly happens when explicit conversion take place?

int main()
{
    int *p ;
    const int a = 20;
    p=(int *)&a;
    *p = *p +10;
    cout<<"p is"<<*p<<"\na is"<<a;
}

output: p is 30 a is 20

krish
  • 95
  • 7

5 Answers5

5

Both C and C++ say that any attempt to modify an object declared with the const qualifier results in undefined behavior.

So as a is object is const qualified, the *p = *p +10; statement invokes undefined behavior.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • The key point here being that hiding a `const` object behind a pointer to a non-`const` type does not make it any less `const`, nor somehow define any modification behavior for it. This is the basic reason for buying into `const`-correctness if you are going to use any `const` data at all. – John Bollinger Jun 06 '15 at 15:11
2

First of - You really shouldn't be doing this. const is a constant, meaning don't change it! :)

Now to explain what happens (I think):

The space on the stack is allocated for both variables, p and a. This is done for a because it has been referenced by an address. If you removed p, you'd effectively remove a as well.

The number 20 is indeed written to the a variable, and modified to 30 via p, which is what is being printed.

The 20 printed is calculated at compile time. Since it is a const, the compiler optimized it away and replaced with 20, as if you did a #define a 20.

mtijanic
  • 2,872
  • 11
  • 26
2

Don't Do That.

If you would write this code in C++ with an explicit cast, you would get something like this:

int main()
{
    int *p ;
    const int a = 20;
    p= const_cast<int*>(&a); // the change
    *p = *p +10;
    cout<<"p is"<<*p<<"\na is"<<a;
}

Now, this code tells a bit more about what's going on: the constant is cast to a non-constant.

If you are writing a compiler, constants are special variables that are allowed to be 'folded' in the const folding phase. Basically this means that the compiler is allowed to change your code into this:

int main()
{
    int *p ;
    const int a = 20;
    p= const_cast<int*>(&a);
    *p = *p +10;
    cout<<"p is"<<*p<<"\na is" << 20; // const fold
}

Because you're also using &a, you tell the compiler to put the value 20 in a memory location. Combined with the above, you get the exact results you describe.

atlaste
  • 30,418
  • 3
  • 57
  • 87
0

This is undefined behavior.

A compiler can assume that nothing is going to change the value of a const object. The compiler knows that the value of "a" is 20. You told the compiler that. So, the compiler actually goes ahead and simply compiles the equivalent of

cout << "p is" << *p << "\na is" << 20;

Your compiler should've also given you a big fat warning, about "casting away const-ness", or something along the same lines, when it tried to compile your code.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
0

Although it is defined as undefined behaviour (as everyone else tells you), it could be that your compiler has allocated a storage location (int) for the const int; that is why the *p= *p + 10 works, but may have repaced a in the output statement with the value 20, as it is supposed to be constant.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41