Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception thrown by 'stol' using Visual Studio but not gcc

The following code throws an exception when it is run under Visual Studio 2013 but not gcc 4.9.2.

The error reported is:

'exception: stol argument out of range'

stol returns a long so the size of temp should be big enough to hold the returned value.

Can anyone explain the behaviour. Is this possibly a compiler bug?

#include <iostream>
#include <exception>
#include <string>
#include <stdexcept>

int main()
{
    const std::string value = "4294967295";   // 0xffffffff

    try
    {
        int64_t temp = std::stol(value);
    }

    catch (std::invalid_argument& ex)
    {
        std::cout << "invalid_argument: " << ex.what() << "\n";
    }

    catch (std::exception& ex)
    {
        std::cout << "exception: " << ex.what() << "\n";
    }

   return 0;
}
like image 996
ksl Avatar asked Dec 08 '22 03:12

ksl


2 Answers

Under Windows the type long is always 32-bits. Since long is a signed integer type this means that the range of long is between -2147483648 and 2147483647 inclusive. On Linux the size of long depends on whether you're compiling for 32-bits or 64-bits.

Since std:stol converts a string to long the result must fit into a long. If it doesn't then the function throws std::out_of_range. To resolve this problem you can use std::stoll which returns a long long, which is guaranteed to be at least 64-bits and so won't ever throw an exception when converting "4294967295". You can also use std::stoul, which converts to a unsigned long, which is is guaranteed to have a range of at least 0 to 4294967295.

(Note that this is not strictly a Visual C++ versus GCC thing. When targeting Windows, GCC also always uses a 32-bit long.)

like image 185
Ross Ridge Avatar answered Jan 28 '23 20:01

Ross Ridge


My bet would be a 32 bits long on visual studio (max 2^31, so overflow) and a 64 bits long on GCC (so nowhere near overflow).

like image 40
MSalters Avatar answered Jan 28 '23 22:01

MSalters