const_cast<int*> doesnt work. Why? [duplicate] - c++

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
const_casting question
The following code tries to change the value of const int a; but it seems a and b both point to same memory address but print out different values. Can somebody explain why?
const int a = 5;
int *b = const_cast<int*>(&a);
*b = 7; //not working why??
cout<<"\nConst Cast: "<<a<<" "<<&a;
cout<<"\nConst Cast: "<<*b<<" "<<b;
cout<<"\nConst Cast: "<<a<<" "<<&a;
/* Output
Const Cast: 5 0027F7FC
Const Cast: 7 0027F7FC
Const Cast: 5 0027F7FC
*/

const_cast is not there to allow you to modify a constant object, but rather to drop the const-ness of a reference/pointer to a non-const object and to be able to call old broken interfaces where the library would not modify, but took a non-const pointer. Modifying an object tha is const is undefined behavior.
Now on the practical test you have. Chances are that the compiler has substituted the value of compile time constant a (which you promised that was 5) into the different uses in the function. When you print a the compiler is printing 5, not reading the value.

You lied to the compiler. You told it that a was const, so it went ahead and treated it as if it was so, replacing instances of a with the compile time constant 5.
What you're doing is undefined behavior.

Related

How to use const cast with pointers in C++? [duplicate]

This question already has answers here:
behavior of const_cast in C++ [duplicate]
(3 answers)
Closed 8 years ago.
What is happening here?
const int a = 0;
const int *pa = &a;
int *p = const_cast<int*>(pa);
*p = 1; // undefined behavior ??
cout << a << *p; // ??
My compiler outputs 0 and 1, but address of 'a' and value of 'p' is the same, so I'm confused how is this possible.
Quote from cppreference:
Even though const_cast may remove constness or volatility from any pointer or reference, using the resulting pointer or reference to write to an object that was declared const or to access an object that was declared volatile invokes undefined behavior.
So yes, modifying constant variables is undefined behavior. The output you see is caused by the fact that you tell the compiler that the value of a will never change, so it can just put a literal 0 instead of the variable a in the cout line.
§7.1.6.1 [dcl.type.cv]/p4:
Except that any class member declared mutable (7.1.1) can be modified,
any attempt to modify a const object during its lifetime (3.8) results
in undefined behavior.
Attempting to write on a const value is undefined behavior, for example to allow the compiler to allocate const values into read only memory (usually in code segment) or inline their value into expressions at compile time, which is what happens in your case.

I have 2 pieces of c++ code that should work the same [duplicate]

This question already has answers here:
Modifying a const through a non-const pointer
(6 answers)
Closed 3 years ago.
This is the first piece of code, that outputs 44:
const int a[] = {3};
int* b = (int*)&a[0];
*b = 4;
cout << a[0] << *b;
And this is the second, that outputs 34:
const int a = 3;
int* b = (int*)&a;
*b = 4;
cout << a << *b;
I have no ideea why is there a difference. Can you guys explain this?
A pointer to a variable declared as const can be assigned only to a pointer that is also declared as const. You are breaking the rule and ideally your compiler should prevent you from doing so.
none of gcc, clang, and MSVC prevent such a mistake and as mentioned in the comments you have undefined behavior instead of at least a warning. However zapcc compiler will make your program to crash with a Segmentation fault.
Besides invoking "undefined behavior" by using casts to circumvent the compiler's checks to change the value of a const variable, the observed result can be explained with the optimizations the compiler likely did:
In the first case, you declare a const array, which likely ends up as data somewhere in RAM.
In the second case, you have a single scalar const value and the compiler probably decided to just use the constant's value which is known at compile time in the output instead of reading that known value from a RAM location. This optimization is also known as constant propagation.
If you didn't take the address of a in your code, it's value would probably not even have a location in data RAM allocated.

Why the deference of pointer to a const is changed while the const is still const? [duplicate]

This question already has answers here:
Two different values at the same memory address
(7 answers)
Closed 5 years ago.
const int c= 7 ;
const int * b= &c ;
int *a = (int *)b ;
*a = 6;
cout<<*a<<endl;
cout<<*b<<endl;
cout<<c<<endl;
I run it by g++ complier , and the output is :
6
6
7
I know it's inadvisable, but I am confused with it. I think the pointer b points to c , which is const , but why *b is changed to 6 while c is still equal to 7 ? they refer to the same stuff , why different?
could you explain how this code works internally ?
§7.1.6.1 [dcl.type.cv]/p4:
Except that any class member declared mutable (7.1.1) can be modified,
any attempt to modify a const object during its lifetime (3.8) results
in undefined behavior.
Undefined behavior means anything can happen. As far as the language is concerned, your program may appear to run correctly, may crash, may produce incorrect results, may chomp up your hard drive, or may blow up the planet.
In this particular case, it is likely that the compiler simply generated code that prints out 7 directly, assuming that c is 7, which it is allowed to do since c is const.
The C-style cast (int *) performs a const_cast on b. Why this is bad has been explained plenty of times on SO.

Strange behavior of const_cast [duplicate]

This question already has answers here:
Two different values at the same memory address
(7 answers)
Closed 5 years ago.
Consider the following code:
I declare a new reference end assign it to value a via const_cast. Then I just increase the reference value print the addresses and values.
#include <iostream>
using namespace std;
int main()
{
const int a = 7;
int &b = const_cast<int&>(a);
++b;
cout<<"Addresses "<<&a<<" "<<&b<<endl;
cout<<"Values "<<a<<" "<<b<<endl;
}
//output
Addresses 0x7fff11f8e30c 0x7fff11f8e30c
Values 7 8
How can i have 2 different values in the same address??
Because modifying a variable declared to be const is undefined behavior, literally anything can happen.
Modifying a constant object gives undefined behaviour, so your program could (in principle) do anything.
One reason for leaving this behaviour undefined is to allow the optimisation of replacing a constant variable with its value (since you've stated that the value can never change). That's what is happening here: a is replaced with the value 7 at compile time, and so will keep that value whatever you try to do to it at run time.
Even though const_cast may remove constness from any pointer or reference, using the resulting pointer or reference to write to an object that was declared const invokes undefined behavior.
check out the example here for more illustration:
http://en.cppreference.com/w/cpp/language/const_cast
Any attempt to modify an object that is itself declared const by means of const_cast results in undefined behavior according to the ISO C++ Standard.
When the we refer "const object", it intends to say that the memory where the object is located may be write-protected. That is, a variable or expression of const type may denote an object stored in write-protected memory and any attempt to modify the object results in undefined behavior
EDIT: Refer this site for more info
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0571.asc

const_casting question [duplicate]

This question already has answers here:
Two different values at the same memory address
(7 answers)
Closed 5 years ago.
I have the following code:
int main(){
const int a = 1;
const int* b(&a);
int* c = const_cast<int*>(b);
*c = 29;
cout<<*c<<a<<*b;
return EXIT_SUCCESS;
}
Why doesnt the value of 'a' change to 29? Does this mean that the constness of a is not removed when const_casting b?
Constant variables also allows the compiler certain optimizations, one of these is that the compiler can keep the value in the registers and not reload it. This improves performance but will not work with variables that changes since these need to be reread. Some compilers even optimize constants by not allocating a variable, but simply replacing the value inline. If you change the variable a to int instead of const int it will work, as it can be read in the documentation about the const_cast operator from IBM:
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.
You can find more information about the problem you are having and why it doesn't work here:
The const_cast operator (IBM)
C++ const_cast usage instead of
C-style
casts
const_cast
confusion
On a side note it can be noted that if you find yourself in need of using the const_cast there is a good chance that you should reconsider your design instead.