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.
Related
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.
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
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
This question already has answers here:
Assigning a reference by dereferencing a NULL pointer
(5 answers)
Closed 9 years ago.
The following code fools around with nullptr pointer and reference:
#include <cstdio>
void printRefAddr(int &ref) {
printf("printAddr %p\n", &ref);
}
int main() {
int *ip = nullptr;
int &ir = *ip;
// 1. get address of nullptr reference
printf("ip=%p &ir=%p\n", ip, &ir);
// 2. dereference a nullptr pointer and pass it as reference
printRefAddr(*ip);
// 3. pass nullptr reference
printRefAddr(ir);
return 0;
}
Question: In C++ standards, are commented statements 1..3 valid code or undefined behavior?
Is this same or different with different versions of C++ (older ones would of course use 0 literal instead of nullptr keyword)?
Bonus question: are there known compilers / optimization options, which would actually cause above code to do something unexpected / crash? For example, is there a flag for any compiler, which would generate implicit assertion for nullptr everywhere where reference is initialized, including passing reference argument from *ptr?
An example output for the curious, nothing unexpected:
ip=(nil) &ir=(nil)
printAddr (nil)
printAddr (nil)
// 2. dereference a nullptr pointer and pass it as reference
Dereferencing a null pointer is Undefined Behaviour, and so whether you pass it as a reference or by value, the fact is that you've dereferenced it and therefore invoked UB, meaning from that point on all bets are off.
You've already invoked UB here:
int &ir = *ip; //ip is null, you cannot deref it without invoking UB.
Since ir is just a shadow of *ip it will not cause an undefined behavior on its own.
The undefined behavior is using a pointer which points to nullptr_t. I mean using *ip. Therefore
int &ir = *ip;
^^^
Causes an UB.
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.