const int a = 1;
int *p = const_cast<int*>(&a);
*p = 2;
cout << “value a=”<< a << endl;
cout << “value *p=” <<*p << endl;
cout << “address a=” <<&a << endl;
cout << “address p=” <<p << endl;
output:
value a=1
value *p=2
address a=0xbff1d48c
address p=0xbff1d48c
WHY???
why same addr ,diff value?
confused.
thank you!
In C++ language it is illegal to attempt to modify constant objects. Such an attempt results in undefined behavior.
In your program the *p = 2 assignment attempts to modify a constant object a. The behavior is undefined. The weird output you observe is exactly that: undefined behavior.
There's no meaningful explanation for undefined behavior.
(Your compiler probably translated the cout << a; statement into cout << 1;, since the value of a cannot legally change. So, regardless of what you do to your a, 1 will always be printed.)
In addition to AndreyT, you might be wondering that if editing a constant gives undefined behavior then why do we need const_cast<> ? The const_cast<> is meant for getting write privilege for the values which are not write protected by birth. Just try below changes and it should give proper behavior:
int b = 1; // 'b' is modifiable
const int a = b;
...
Related
I'm a bit confused what happened in the following code:
const int e = 2;
int* w = ( int* ) &e; // (1) cast to remove const-ness
*w = 5; // (2)
cout << *w << endl; // (3) outputs 5
cout << e << endl; // (4) outputs 2
cout << "w = " << w << endl; // (5) w points to the address of e
cout << "&e = " << &e << endl;
In (1), w points to the address of e. In (2), that value was changed to 5. However, when the values of *w and e were displayed, their values are different. But if you print value of w pointer and &e, they have the same value/address.
How come e still contained 2, even if it was changed to 5? Were they stored in a separate location? Or a temporary? But how come the value pointed by w is still the address of e?
As I said in my comment, once you modified the const value you are in undefined behaviour land, so it doesn't make much sense to talk about what is happening. But what the hell..
cout << *w << endl; // (3) outputs 5
cout << e << endl; // (4) outputs 2
At a guess, *w is being evaluated at runtime, but e is being treated as a compile time constant
I suspect that you're tripping up the compiler. It doesn't expect you to play dirty tricks with e, so when it sees the line:
cout << e << endl;
It simply inserts the value 2 instead of looking for the actual value. You can verify (or disprove) this by looking at the disassembly of your program.
I'm guessing that the compiler has optimised the value output. It sees that e is const (so, it can't change -- in theory) and changes cout << e << endl; to cout << 2 << endl;. However, e still has to exist because it's used by w, so w correctly takes its address and modifies its value, but you don't see that in the cout.
Moral of the story -- only declare things const when you actually want to be const. Casting away constness is not a good idea.
The only thing I can think of is the compiler has some how optimised the code in such a way that any references to e are replaced with a value of 2 even though it assigns memory for e
so in effect (affect?) the line at comment (4) is 'optimized' to be
cout << "2" << endln;
I guess the compiler uses the constness to optimizes out the variable and insert a fixed value into the code.
This is covered by section [dcl.type.cv]/4 of the C++14 standard (earlier standards had similar text too):
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
e is a const object, and *w = 5; attempts to modify that object, therefore the result is undefined behavior.
I'd like to know what is happening internally and its relation to values displayed.
The code is:
# include <iostream>
int main(){
using namespace std;
const int a = 10;
int* p = &a; //When compiling it generates warning "initialization from int* to
//const int* discard const -- but no error is generated
cout << &a <<"\t" << p <<endl; //output: 0x246ff08 0x246ff08 (same values)
cout << a << "\t" << *p << endl; //output: 10 10
//Now..
*p = 11;
cout << &a <<"\t" << p <<endl; //output: 0x246ff08 0x246ff08 (essentially,
//same values and same as above, but..)
cout << a << "\t" << *p << endl; //output: 10 11
return 0;
}
QUESTION: If p = address-of-a, how come a=10, but *p = (goto address of a and read value in the memory location) = 11?
cout << a << "\t" << *p << endl; //output: 10 11
You lied to the compiler and it got its revenge.
With:
const int a = 10;
you promised you'll never modify a object.
You promised not to modify a, and the compiler believed you. So it decided to optimise away the reading of a, because it trusted you. You broke your promise.
Having said that, a real C++ compiler won't compile your code because int* p = &a is illegal. So perhaps you are lying to us as well. Or perhaps you need to get a real C++ compiler.
Just like Ouah said compiler has taken its revenge
but I disagree with you that it doesn't give any error
const int a = 10;
int* p = &a;
You cannot assign constant to a non constant pointer.
In C, this is undefined behavior. In C++, this won't compile. It's been repeated by David Heffernan multiple times but it is worth repeating. Here is the error you should get on a modern compiler:
main.cpp:7:10: error: cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'
int* p = &a; //When compiling it generates warning "initialization from int* to
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the correct answer for cout << c++ << c;?
I just ouputted text, when I suddenly noticed.
#include <iostream>
int main()
{
int array[] = {1,2,3,4};
int *p = array;
std::cout << *p << "___" << *(p++) << "\n";
// output is 1__1. Strange, but I used brackets! it should be at
// first incremented, not clear.
p = array;
std::cout << *p << "___" << *(++p) << "\n";
// output is 2_2 fine, why first number was affected? I didn't intend
// to increment it, but it was incremented
p=array;
std::cout << *p << "___" << *(p + 1) << "\n";
// output is 1_2 - as it was expected
p = array;
return 0;
}
Such behaviour is strange for me, why is it so?
You are causing undefined behaviour, so anything can happen and there's no point in speculating about why.
The expression
std::cout<<*p<<"___"<<*(p++)<<"\n"
Is one example: the order of evaluation of all the things between << is unspecified, so *p and *(p++) are unsequenced with respect to each other (i.e. the compiler is not required do do either one first). You are not allowed to modify a variable and then use it without the modification and usage being sequenced, and so this causes undefined behaviour.
The same thing applies to all the other places in that program where a variable is modified and used unsequenced separately in the same expression.
First, sorry for possible question redundancy.
Doing some little experiments with C/C++ pointers in GCC I encountered this somewhat weird behaviour when bypassing constantness of value at the pointer address.
#include <iostream>
int main()
{
using namespace std;
const double number = 100;
//bypassing constantess of pointed-to value
double * pointer_to_value = (double *) &number;
*pointer_to_value += 200;
cout << "Adress of number: " << &number << "\tValue of number: " << number << endl <<
" Pointer value: " << pointer_to_value << "\tDereferencing pointer: " << *pointer_to_value;
return 0;
}
I would expect both form of checking the value yielding same results. Location of value is same in both cases. Program generates following output, however:
Adress of number: 0x22ff30 Value of number: 100
Pointer value: 0x22ff30 Dereferencing pointer: 300
Anyone capable of explaining?
Thanks in advance.
It's undefined behaivor.
It's irrelevant why exactly it happens (actually because the compiler inlines the value).
"UnConsting” const value via pointer is a Undefined Behavior.
So it is not posible to define a behavior not defined by the Standard.
Compiler optimization. Compiler doesn't expect you to try and trick it like that, it knows that the value is const, so it just cached it. Try to compile it without any optimization, and see if it makes any difference.
Generally the meaning of const is:
constant - the object shall not be modified. Attempt to do so results in undefined behavior. On most of the compilers it is compile-time error.
Compiler optimization. You can overcome that by adding volatile keyword to the variable.
#include <iostream>
int main()
{
using namespace std;
volatile const double number = 100;
//bypassing constantess of pointed-to value
double * pointer_to_value = (double *) &number;
*pointer_to_value += 200;
cout << "Adress of number: " << &number << "\tValue of number: " << number << endl <<
" Pointer value: " << pointer_to_value << "\tDereferencing pointer: " << *pointer_to_value;
return 0;
}
My guess is that gcc has done some optimizations on your behalf, replacing the reference to << number with << 100. Should be possible to verify by looking at the generated asm code.
I'm a bit confused what happened in the following code:
const int e = 2;
int* w = ( int* ) &e; // (1) cast to remove const-ness
*w = 5; // (2)
cout << *w << endl; // (3) outputs 5
cout << e << endl; // (4) outputs 2
cout << "w = " << w << endl; // (5) w points to the address of e
cout << "&e = " << &e << endl;
In (1), w points to the address of e. In (2), that value was changed to 5. However, when the values of *w and e were displayed, their values are different. But if you print value of w pointer and &e, they have the same value/address.
How come e still contained 2, even if it was changed to 5? Were they stored in a separate location? Or a temporary? But how come the value pointed by w is still the address of e?
As I said in my comment, once you modified the const value you are in undefined behaviour land, so it doesn't make much sense to talk about what is happening. But what the hell..
cout << *w << endl; // (3) outputs 5
cout << e << endl; // (4) outputs 2
At a guess, *w is being evaluated at runtime, but e is being treated as a compile time constant
I suspect that you're tripping up the compiler. It doesn't expect you to play dirty tricks with e, so when it sees the line:
cout << e << endl;
It simply inserts the value 2 instead of looking for the actual value. You can verify (or disprove) this by looking at the disassembly of your program.
I'm guessing that the compiler has optimised the value output. It sees that e is const (so, it can't change -- in theory) and changes cout << e << endl; to cout << 2 << endl;. However, e still has to exist because it's used by w, so w correctly takes its address and modifies its value, but you don't see that in the cout.
Moral of the story -- only declare things const when you actually want to be const. Casting away constness is not a good idea.
The only thing I can think of is the compiler has some how optimised the code in such a way that any references to e are replaced with a value of 2 even though it assigns memory for e
so in effect (affect?) the line at comment (4) is 'optimized' to be
cout << "2" << endln;
I guess the compiler uses the constness to optimizes out the variable and insert a fixed value into the code.
This is covered by section [dcl.type.cv]/4 of the C++14 standard (earlier standards had similar text too):
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
e is a const object, and *w = 5; attempts to modify that object, therefore the result is undefined behavior.