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

2.4k views Asked by At

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;
}
5

There are 5 answers

0
Ross Ridge On BEST ANSWER

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.)

1
MSalters On

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).

1
marom On

From

http://en.cppreference.com/w/cpp/string/byte/strtol

strtol returns a long and you need strtoll to get a long long

0
Ben Voigt On

Not a compiler bug, the problem is your invalid assumptions.

The Standard allows LONG_MAX to be as low as 2147483647, so

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

simply is not true.

0
AudioBubble On

So just use std::stoul instead.

At first glance the string constant certainly exceeds the maximum value a long can assume, but not the max value an unsigned long can have...