pointer to a const int in c++ - c++

While I was learning about const variables in c++, I tried this :
#include <iostream>
int main()
{
const int p = 20;
int* a = const_cast<int*>(&p);
*a = 10;
std::cout<<"Value at a: "<<(*a)<<std::endl;
std::cout<<"Value of p: "<<p<<std::endl;
std::cout<<"Their addresses : "<<std::endl;
std::cout<<a<<" "<<&p<<std::endl;
return 0;
}
and it produces the output:
Value at a: 10
Value of p: 20
Their addresses :
0x7fff4646d7d4 0x7fff4646d7d4
Seemingly I assigned the value 10 to the memory address of p, but their values come out different. Why is it so?

Attempting to modify an object that was originally declared const gives you undefined behaviour.
ยง7.1.6.1/4 [dcl.type.cv] Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
Chances are, your compiler is replacing all occurences of p in your code with the value 20, since you have promised that it will not change. So the line that prints p has changed to:
std::cout<<"Value of p: "<<20<<std::endl;
So it prints 20 regardless of whether you modified the original object. Of course, since you have undefined behaviour, this kind of reasoning is fruitless and you should not invoke undefined behaviour in your program.

Related

const_cast doesn't change the value [duplicate]

This question already has answers here:
const_cast doesn't work c++? [duplicate]
(3 answers)
Closed 6 years ago.
After const_cast, the value does not change in the main function. But changes when calling an external function, still prints the old value in the main (where const int is initialized first).
int main() {
const int i = 5;
int* p = const_cast<int*>(&i);
*p = 22;
std::cout<<i;
return 0;
}
Output is 5, why? The watch-window shows value of i = 22:
So why does it print 5 ? The output differs if I call an external function:
void ChangeValue(const int i) {
int* p = const_cast<int*>(&i);
*p = 22;
std::cout<<i; //Here the value changes to 22
}
int main() {
const int i = 5;
ChangeValue(i); //Value changes to 22 in the ChangeValue function
std::cout<<i // It again prints 5.
}
Why is the value not changed even if the value changes after calling the ChangeValue function?
I get the same output on a Linux Platform. Could someone please add clarity to my confusion?
Trying to modify a constant value leads to undefined behavior, just don't do it.
As for why it doesn't change, the compiler sees that it is a compile-time constant and may store it in a read-only segment.
For the second program, the variable i can't be stored in a read-only segment, it's stored on the stack like any other local variable. However, since you marked i as constant attempting to modify it is still undefined behavior.
The reason the main program prints the old value, is because you pass the variable by value meaning it gets copied into the local variable i in the ChangeValue function. If the variable wasn't a constant in the main or the ChangeValue function, the value of i in the main function would still not change.
If you change the ChangeValue function to take its argument by reference, you might get the same behavior as the first program.

Conversion from const int to int giving strange results.Can anyone explain the reason for the strange results

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
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.
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.
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.
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.
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.

Can a non-const pointer modify a const var int c++?

Here is my test code:
#define print(A) cout << #A << " = " << A << endl;
int main()
{
const int e = 2;
int *p = (int *)&e;
*p = 4;
print(e);
print(*p);
print(&e);
print(p);
}
Result:
e = 2;
*p = 4;
&e = 0xbfc6b458;
p = 0xbfc6b458;
Since "p" points to "e" according to their identical address, how can *p and "e" be different??? This can be dangerous, right?
Casting away const is legal; using the pointer (or reference) thus acquired to (attempt to) modify a const object is illegal.
Your code results in undefined behaviour; it can do anything and it doesn't have to make any sense.
Modifying a constant variable in any way results in an Undefined Behavior.
So yes this is dangerous.
An Undefined Behavior means that any behavior is possible and you cannot expect any valid behavior. The compiler is free to give you any results and it is allowed by the Standard to do so. Once an UB is invoked the program is not a valid program anymore.So best is to avoid any code which causes an UB.
They can be different because "e" is a const, so any decent compiler will plug in the value at compile time instead of reading it from memory.
Since you take the address there's still a "real" variable for it, but it's not actually used in your case.
And you're "lucky" that you could modify the value at all; since it was declared "const", the compiler could have placed it into readonly memory.
Either way, modifying a const value yields "undefined behavior". Lucky for us, you didn't destroy the world with your foolish game.
You're attempting to write to a constant variable (yes, the name is pretty oxymoron but I digress) which is undefined behavior.
You are casting away const. which is giving you wrong value which is Undefined behaviour.
It should be either
int e = 2;
int* p = (int *)&e;
*p = 4;
or
const int e = 2;
const int* p = (const int *)&e;
*p = 4;
latter one will give you compilation error as you are writting to a const.
Define variable:
const int e = 2;
directive const tell c/c++ compiler check whether L-value of e variable, compiler will prevent your code assign new value for e.
int* p = (int *)&e;
p is a pointer (also int 4 bytes), can be assigned any value , p = (((int *) e ) -2)+2. The compiler no need to check *p whether *p is constant. I think that is a flexible of c/c++ languages, the better way is avoiding pointer.

what are the differences between these returning-address of local functions?

I have the following functions (wrote in Visual C++ 2005)
int &getInt_1()
{
int a = 5;
int &p = a;
int p1 = p; // Line 1
return p1;
}
int &getInt_2()
{
int a = 5;
int &p = a;
return p;
}
As I have known so far, both the above functions return address of local variable. If I am right, then I have some questions as follows:
What are the differences between above functions? Why getInt_1() gets warning from the compiler ("returning address of local variable") while getInt_2() does not?
What does Line 1 mean? After Line 1, does p1 become a reference to a as well?
getInt_1 returns a reference to p1. getInt_2 returns a reference to a. Both are the same undefined behavior, don't do it. VC should give a warning on both.
No, you just copy the value.
1) Both are undefined behavior, because of what you pointed out. It's probably an oversight in MSVS.
2) No, p1 does not become a reference itself. That line is equivalent to int p1 = a;
In the first case, it's easy for the compiler to show that you're returning a reference to a local variable; in the second case it's harder, because it just has an arbitrary reference that happens to refer to a local variable. That's probably why you get the warning in the first case but not the second.
And no, in the first case p1 is just a normal int, not an int&.

C++ Pointer Confusion

Please Explain the following code
#include <iostream>
using namespace std;
int main()
{
const int x = 10;
int * ptr;
ptr = (int *)( &x ); //make the pointer to constant int*
*ptr = 8; //change the value of the constant using the pointer.
//here is the real surprising part
cout<<"x: "<<x<<endl; //prints 10, means value is not changed
cout<<"*ptr: "<<*ptr<<endl; //prints 8, means value is changed
cout<<"ptr: "<<(int)ptr<<endl; //prints some address lets say 0xfadc02
cout<<"&x: "<<(int)&x<<endl; //prints the same address, i.e. 0xfadc02
//This means that x resides at the same location ptr points to yet
//two different values are printed, I cant understand this.
return 0;
}
*ptr = 8;
This line causes undefined behavior because you are modifying the value of a const qualified object. Once you have undefined behavior anything can happen and it is not possible to reason about the behaviour of the program.
Since x is a const int, the compiler will most likely, in the places where you use x, directly substitute the value that you've initialized with (where possible). So the line in your source code:
cout<<"x: "<<x<<endl;
will be replaced by this at compile time:
cout<<"x: "<<10<<endl;
That's why you still see 10 printed.
But as Charles explained, the behaviour is undefined, so anything could happen with code like this.