akash
akash

Reputation: 1801

Pointer to a constant

#include <iostream>
using namespace std;

int main(void)
{
   const int a1 = 40;
   const int* b1 = &a1;
   int * c1 = (int *)(b1);
   *c1 = 'A';
cout<<*c1<<endl;
cout<<a1<<endl;
   return 0;
}

o/p:

65
40

Can anyone explain the output?

Upvotes: 2

Views: 152

Answers (3)

user2404501
user2404501

Reputation:

The assignment *c1 = 'A'; writes to unwritable memory. Hopefully you know that's bad. I'll assume there's a less stupid reason for writing the code and asking people to explain it.

Maybe you want an example of how implementation choices can lead to the result you saw. Here's one: the compiler optimizes away all the reads of the variable: to print *c1 it says "I don't need to look at *c1, I know what's in it, I just put a 65 there. I'll print that." And then to print a1 it says "I don't need to look at a1, I initialized it to 40 and it's not allowed to change, so I'll just print that." Then it looks at the *c1 assignment and says "I don't really need to assign that value, since I'm not going to use it."

Or maybe that last part doesn't happen. The variable is local, so it's likely to be on the stack, in a writable page, without meaningful run-time enforcement of its constness.

Upvotes: 1

juanchopanza
juanchopanza

Reputation: 227628

What you are doing is casting away the constness of something that is const (variable a1). This results in undefined behaviour (UB). In practice it means that anything could happen. What you observe is one manifestation of "anything".

Usually answers to questions involving UB include wild examples of crazy things that could happen. I will break with tradition by refraining from that.

Upvotes: 6

Mats Petersson
Mats Petersson

Reputation: 129524

This is an example of "undefined behaviour", which explains why you are getting two different outputs "from one variable". Undefined behaviour, means "not necessarily what you expect, but could be what you expect".

Since you have "promised" the compiler that you are not going to change a1, then the compiler simply puts the constant 40 into the cout << a1 << endl line, rather than actually reading the value in a1. This is an optimization that is perfectly valid for a constant. The fact that you then jump through hoops to manage to "loose" the constness of that variable and write to it doesn't really change the fact that you promised not to change the value.

Upvotes: 2

Related Questions