' stol'抛出的例外情况使用Visual Studio而不是gcc

时间:2015-06-09 20:06:38

标签: c++ c++11 exception visual-studio-2013 gcc4.9

以下代码在Visual Studio 2013下运行但不是gcc 4.9.2时会抛出异常。

报告的错误是:

  

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

stol会返回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;
}

5 个答案:

答案 0 :(得分:5)

我的赌注是视觉工作室上的32位long(最多2 ^ 31,因此溢出)和GCC上的64位long(因此无法接近溢出)。

答案 1 :(得分:5)

在Windows下,long类型始终为32位。由于long是有符号整数类型,因此long的范围介于-2147483648和2147483647之间。在Linux上,long的大小取决于您是否正在编译32位或64位。

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

(请注意,这不是严格意义上的Visual C ++与GCC的对比。在针对Windows时,GCC也始终使用32位long。)

答案 2 :(得分:3)

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

标准允许LONG_MAX低至2147483647,所以

  

stol会返回long,因此temp的大小应该足以保存该值。

根本不是真的。

答案 3 :(得分:1)

所以请改用std::stoul

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

答案 4 :(得分:0)

来自

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

strtol返回一个长的,你需要strtoll来获得很长的