Is there a function in C++ (C++11, if it makes a difference) that converts a string to a uintptr_t
or intptr_t
? I can always use atoll()
and cast it afterward, but it'd be nice to get a function that does 32-bit for 32-bit machines and 64-bit for 64-bit machines.
char* c = "1234567";
uintptr_t ptr = atoptr(c); // a function that does this;
This is an IMO surprising gap in C++. While stringstream
does the job, it is quite a heavy tool for such a simple task. Instead, you can write an inline function that calls the correct variation of strtoul
based on the type sizes. Since the compiler knows the correct size it will be smart enough to replace calls to the function with calls to strtoul or strtoull. I.e., something like the following:
inline uintptr_t handleFromString(const char *c, int base = 16)
{
// See if this function catches all possibilities.
// If it doesn't, the function would have to be amended
// whenever you add a combination of architecture and
// compiler that is not yet addressed.
static_assert(sizeof(uintptr_t) == sizeof(unsigned long)
|| sizeof(uintptr_t) == sizeof(unsigned long long),
"Please add string to handle conversion for this architecture.");
// Now choose the correct function ...
if (sizeof(uintptr_t) == sizeof(unsigned long)) {
return strtoul(c, nullptr, base);
}
// All other options exhausted, sizeof(uintptr_t) == sizeof(unsigned long long))
return strtoull(c, nullptr, base);
}
This will be easy to update if you ever decide to change the type of the handle. If you like angle brackets, you can also do something equivalent with templates though I don't see how that could be clearer.
Lastly, you can also use sscanf
with the %tx
format, i.e.
inline uintptr_t handleFromString(const char *c)
{
ptrdiff_t h;
sscanf(c, "%tx", &h); // only hex supported, %td for decimal.
return (uintptr_t)h;
}
Unfortunately, no compiler that I tried on the Compiler Explorer managed to optimize the code in a way that removes the call to sscanf.
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