'stol' 使用 Visual Studio 而不是 gcc 引发的异常
Exception thrown by 'stol' using Visual Studio but not gcc
以下代码在 Visual Studio 2013 下 运行 而不是 gcc 4.9.2 时抛出异常。
报告的错误是:
'exception: stol argument out of range'
stol
returns a long
因此 temp
的大小应该足以容纳返回值。
任何人都可以解释这种行为。这可能是编译器错误吗?
#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;
}
我的赌注是 visual studio 上的 32 位 long
(最大 2^31,所以溢出)和 GCC 上的 64 位 long
(所以离溢出还差得很远)。
来自
http://en.cppreference.com/w/cpp/string/byte/strtol
strtol returns long 需要 strtoll 才能得到 long long
在 Windows 下,类型 long
总是 32 位。由于 long
是有符号整数类型,这意味着 long
的范围在 -2147483648 和 2147483647 之间(含)。在 Linux 上,long
的大小取决于您是针对 32 位还是 64 位进行编译。
由于 std:stol
将字符串转换为 long
,因此结果必须适合 long
。如果不是,则函数 throws std::out_of_range
。要解决此问题,您可以使用 std::stoll
which returns a long long
,保证至少为 64 位,因此在转换 [=20= 时不会抛出异常].您还可以使用 std::stoul
,它转换为 unsigned long
,保证范围至少为 0 到 4294967295。
(请注意,这并不是严格意义上的 Visual C++ 与 GCC 的对比。当以 Windows 为目标时,GCC 也始终使用 32 位 long
。)
不是编译器错误,问题是您的假设无效。
标准允许 LONG_MAX
低至 2147483647,因此
stol
returns a long
so the size of temp
should be big enough to hold the value.
根本不是真的。
所以只需使用 std::stoul
即可。
乍一看,字符串常量肯定超过了 long
可以假设的最大值,但没有超过 unsigned long
可以假设的最大值...
以下代码在 Visual Studio 2013 下 运行 而不是 gcc 4.9.2 时抛出异常。
报告的错误是:
'exception: stol argument out of range'
stol
returns a long
因此 temp
的大小应该足以容纳返回值。
任何人都可以解释这种行为。这可能是编译器错误吗?
#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;
}
我的赌注是 visual studio 上的 32 位 long
(最大 2^31,所以溢出)和 GCC 上的 64 位 long
(所以离溢出还差得很远)。
来自
http://en.cppreference.com/w/cpp/string/byte/strtol
strtol returns long 需要 strtoll 才能得到 long long
在 Windows 下,类型 long
总是 32 位。由于 long
是有符号整数类型,这意味着 long
的范围在 -2147483648 和 2147483647 之间(含)。在 Linux 上,long
的大小取决于您是针对 32 位还是 64 位进行编译。
由于 std:stol
将字符串转换为 long
,因此结果必须适合 long
。如果不是,则函数 throws std::out_of_range
。要解决此问题,您可以使用 std::stoll
which returns a long long
,保证至少为 64 位,因此在转换 [=20= 时不会抛出异常].您还可以使用 std::stoul
,它转换为 unsigned long
,保证范围至少为 0 到 4294967295。
(请注意,这并不是严格意义上的 Visual C++ 与 GCC 的对比。当以 Windows 为目标时,GCC 也始终使用 32 位 long
。)
不是编译器错误,问题是您的假设无效。
标准允许 LONG_MAX
低至 2147483647,因此
stol
returns along
so the size oftemp
should be big enough to hold the value.
根本不是真的。
所以只需使用 std::stoul
即可。
乍一看,字符串常量肯定超过了 long
可以假设的最大值,但没有超过 unsigned long
可以假设的最大值...