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