I am trying to adapt an existing code to a 64 bit machine. The main problem is that in one function, the previous coder uses a void* argument that is converted into suitable type in the function itself. A short example:
void function(MESSAGE_ID id, void* param) { if(id == FOO) { int real_param = (int)param; // ... } }
Of course, on a 64 bit machine, I get the error:
error: cast from 'void*' to 'int' loses precision
I would like to correct this so that it still works on a 32 bit machine and as cleanly as possible. Any idea ?
The "address of" operator This is the best way to attach a pointer to an existing variable: int * ptr; // a pointer int num; // an integer ptr = # // assign the address of num into the pointer // now ptr points to "num"!
Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
So a pointer to an int means a variable whose value is the memory address of an int, and a pointer to a pointer to an int means a variable whose value is the memory address of a pointer to int, and the value of that pointer to int is a memory address of an int.
Well, yes, you can certainly do that, but again, you should consider the actual numerical value of that integer as meaningless. If you have a 32-bit pointer, you can store it in a 32-bit integer, and vice versa, but what that numerical value of the integer means, that I would not place any value on.
I'd say this is the modern C++ way:
#include <cstdint> void *p; auto i = reinterpret_cast<std::uintptr_t>(p);
EDIT:
So the right way to store a pointer as an integer is to use the uintptr_t
or intptr_t
types. (See also in cppreference integer types for C99).
These types are defined in <stdint.h>
for C99 and in the namespace std
for C++11 in <cstdint>
(see integer types for C++).
C++11 (and onwards) Version
#include <cstdint> std::uintptr_t i;
C++03 Version
extern "C" { #include <stdint.h> } uintptr_t i;
C99 Version
#include <stdint.h> uintptr_t i;
In C there is only one cast and using the C cast in C++ is frowned upon (so don't use it in C++). In C++ there are different types of casts, but reinterpret_cast
is the correct cast for this conversion (see also here).
C++11 Version
auto i = reinterpret_cast<std::uintptr_t>(p);
C++03 Version
uintptr_t i = reinterpret_cast<uintptr_t>(p);
C Version
uintptr_t i = (uintptr_t)p; // C Version
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With