std :: stoul不会抛出std :: out_of_range

doo*_*sta 3 c++ g++ exception g++4.8

考虑以下代码:

#include <iostream>
#include <cstring>
#include <cerrno>

int main() {
    unsigned long num = strtoul("0xFFFFFFFFFFFF11223344556677889900AABBCCDDEEFF", NULL, 16);
    std::cout << std::strerror(errno) << "\n";
    unsigned long num2 = std::stoul("0xFFFFFFFFFFFF11223344556677889900AABBCCDDEEFF");
    std::stoul("hello world");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

预计该代码会从strerror打印一些“超出范围”,然后根据文档抛出out_of_range异常。它永远不会到达最后的污迹线。

实际上,它不会引发第二个stoul语句。我已经尝试了GCC 4.8.5和MinGW 8.2.0,但均未引发out_of_range异常,并且仅在最后一个stoul语句上传递了invalid_argument。

这是应该报告的错误,还是我缺少某些东西,并且这是预期的行为?

Yks*_*nen 8

为默认的基本std::stoul是10
stoul读取0x是无效的,因此字符串的其余部分被忽略,并且数值0返回。

使用与相似的语法strtoul

unsigned long num2 = std::stoul("0xFFFFFFFFFFFF11223344556677889900AABBCCDDEEFF", nullptr, 16);
Run Code Online (Sandbox Code Playgroud)

或自动扣除数字基数:

unsigned long num2 = std::stoul("0xFFFFFFFFFFFF11223344556677889900AABBCCDDEEFF", nullptr, 0);
Run Code Online (Sandbox Code Playgroud)

以上两个版本都会抛出。在线查看!

  • 是的,关键是该函数解释字符串中的整数,而不是整数,该整数不一定是整个字符串。我认为OP应该使用pos来检测这种情况,假设需要捕获错误(而不只是通过更改基数来解决它,从而使错误消失) (3认同)