简体   繁体   中英

atoi() equivalent for intptr_t/uintptr_t

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. Ie, 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, ie

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM