Исключение, генерируемое stol с использованием Visual Studio, но не gcc
Следующий код выдает исключение, когда он запускается под 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 ответов
Под виндой тип long
всегда 32-битный поскольку long
является целочисленным типом со знаком, это означает, что диапазон long
от -2147483648 до 2147483647 включительно. На линуксе размер long
зависит от того, компилируете ли вы для 32-битной или 64-битной.
поскольку std:stol
преобразует строку в long
результат должен вписываться в long
, Если это не так, то функция бросаетstd::out_of_range
, Для решения этой проблемы вы можете использовать std::stoll
который возвращает long long
, который гарантированно будет по крайней мере 64-битным и поэтому никогда не будет выдавать исключение при преобразовании "4294967295"
, Вы также можете использовать std::stoul
, который преобразует в unsigned long
, который гарантированно имеет диапазон от 0 до 4294967295.
(Обратите внимание, что это не совсем Visual C++ против GCC. При нацеливании на Windows, GCC также всегда использует 32-разрядный long
.)
Моя ставка будет 32 бит long
на visual studio (максимум 2^31, переполнение) и 64 бита long
на GCC (так что далеко не переполнение).
Не ошибка компилятора, проблема в ваших неверных предположениях.
Стандарт позволяет LONG_MAX
быть столь же низким, как 2147483647, так
stol
возвращаетlong
поэтому размерtemp
должно быть достаточно большим, чтобы держать значение.
просто не соответствует действительности.
Так что просто используйте std::stoul
вместо.
На первый взгляд строковая константа, безусловно, превышает максимальное значение long
Можно предположить, но не максимальное значение unsigned long
могу иметь...
От
http://en.cppreference.com/w/cpp/string/byte/strtol
strtol возвращает long, и вам нужен strtoll, чтобы получить long long