Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::stoul not throwing std::out_of_range

Consider following code:

#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;
}

This code is expected to print some "Out of range" from strerror and then to throw out_of_range exception according to documentation. It should never reach the last stoul line.

In practice, it does not throw on the second stoul statement. I have tried GCC 4.8.5 and MinGW 8.2.0, both failed to throw the out_of_range exception and only delivered invalid_argument on the last stoul statement.

Is this a bug that should be reported or am I missing something and this is expected behaviour?

like image 517
doomista Avatar asked Jan 26 '23 04:01

doomista


1 Answers

Default base for std::stoul is 10.
stoul reads 0, x is invalid so the rest of the string is ignored and numeric value 0 is returned.

Use similar syntax as in strtoul:

unsigned long num2 = std::stoul("0xFFFFFFFFFFFF11223344556677889900AABBCCDDEEFF", nullptr, 16);

Or with automatic deduction of numeric base:

unsigned long num2 = std::stoul("0xFFFFFFFFFFFF11223344556677889900AABBCCDDEEFF", nullptr, 0);

Both of the above versions will throw. See it online!

like image 124
Yksisarvinen Avatar answered Jan 28 '23 18:01

Yksisarvinen