4

以下代码在 Visual Studio 2013 而非 gcc 4.9.2 下运行时会引发异常。

报告的错误是:

'例外:stol 参数超出范围'

stol返回 along所以大小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;
}
4

5 回答 5

5

我的赌注是longVisual Studio 上的 32 位(最大 2^31,所以溢出)和longGCC 上的 64 位(所以远不及溢出)。

于 2015-06-09T20:09:16.213 回答
5

在 Windows 下,类型long始终为 32 位。由于long是有符号整数类型,这意味着 的范围long介于 -2147483648 和 2147483647 之间。在 Linux 上,大小long取决于您是针对 32 位还是 64 位进行编译。

由于std:stol将字符串转换为long结果必须适合long. 如果没有,则该函数将抛出std::out_of_range. 要解决此问题,您可以使用std::stollwhich 返回 a long long,它保证至少为 64 位,因此在转换时不会抛出异常"4294967295"。您也可以使用std::stoul, 转换为 a unsigned long,保证其范围至少为 0 到 4294967295。

(请注意,这并不是严格意义上的 Visual C++ 与 GCC 的事情。当面向 Windows 时,GCC 也总是使用 32 位的long.)

于 2015-06-09T20:14:37.580 回答
3

不是编译器错误,问题是您的假设无效。

标准允许LONG_MAX低至 2147483647,所以

stol返回 along所以 的大小temp应该足够大以容纳该值。

根本不是真的。

于 2015-06-09T20:14:52.353 回答
1

所以就std::stoul改用吧。

乍一看,字符串常量肯定超过了 along可以假设的最大值,但不是 a 可以具有的最大值unsigned long......

于 2015-06-09T23:22:09.970 回答
0

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

strtol 返回一个 long 并且你需要 strtoll 来获得一个 long long

于 2015-06-09T20:10:33.880 回答