The essence of your problem is that your code is designed to shoot yourself in the foot, and you're misinterpreting the foot wound as a natural cause.
For example, in the environment you're compiling for, long long
actually is large enough to store a pointer†, so there's no reason you couldn't write code like this:
int x = 1923;
long long xpointer;
xpointer = reinterpret_cast<long long>(&x); //Valid on a 64-bit x86 CPU compiled with GCC
cout << xpointer << endl;
return 0;
But your code is instead the equivalent of xpointer = reinterpret_cast<int>(&x);
, which is not valid in your environment. int
is not the same size as long long
†, and if you're casting to the latter, you need an express cast to that type. Not to an intermediate type (int
) that then gets implicitly expanded to the proper type (long long
), which will instead cause a warning or error.
In the future, if you do intend to store a pointer as an integer, you should prefer std::intptr_t
instead, as [iff that type is defined for your environment] it is guaranteed to be large enough to store a pointer as an integer.
int x = 1923;
intptr_t xpointer = reinterpret_cast<intptr_t>(&x); //Guaranteed to be valid if intptr_t is defined
cout << xpointer << endl;
return 0;
†Be aware that not all environments have the same sizes of integers (including int
and long long
) as GCC on a 64-bit x86 environment. In your case, that's 32-bits and 64-bits respectively, but those numbers, especially the former, may be different if you are instead compiling for a different environment.
If you then intend to actually use the pointer stored in xpointer
to modify the data it points to, you need to then cast the pointer back. You cannot manipulate the data pointed to by xpointer
without instructing the compiler to treat it as a pointer.
int x = 1923;
intptr_t xpointer = reinterpret_cast<intptr_t>(&x);
cout << xpointer << endl;
int* ptr = reinterpret_cast<int*>(xpointer); //Legal If-and-only-If xpointer has not been changed
*ptr = 2019;
cout << x << endl; //Should print "2019"
cout << *ptr << endl; //Should print "2019"
return 0;
Be warned though that if you attempt to perform any kind of arithmetic operation on the pointer itself, you'll quickly veer into Undefined Behavior territory, and the behavior of your program can no longer be guaranteed:
int x = 1923;
intptr_t xpointer = reinterpret_cast<intptr_t>(&x);
cout << xpointer << endl;
int* ptr = reinterpret_cast<int*>(xpointer); //Legal If-and-only-If xpointer has not been changed
*ptr = 2019;
cout << x << endl; //Should print "2019"
xpointer++;//Legal, but...
int* ptr2 = reinterpret_cast<int*>(xpointer);
*ptr2 = 2020; //This is now undefined behavior
cout << x << endl; //Legal on its own, but because of preceeding undefined behavior,
//this may not do what you expect.
return 0;