Исключение, генерируемое 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

Другие вопросы по тегам