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
d开发者_运维知识库ouble * 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.
精彩评论