Вопрос

Следующий код не дает предупреждения с G ++ 4.1.1 и -Wall.

int octalStrToInt(const std::string& s)
{    
    return strtol(s.c_str(), 0, 8);
}

Я ожидал предупреждения, потому что Стрит возвращает long int Но моя функция возвращает только равную int. Анкет Могут ли другие компиляторы излучать здесь предупреждение? Стоит ли в этом случае отдать возвратную ценность в Int в качестве хорошей практики?

Это было полезно?

Решение

Вам может понадобиться флаг -Wonversion, чтобы включить эти предупреждения. Тем не менее, это не предупреждает о длинная -> инт, поскольку они такого же размера с GCC (значение не изменится из -за преобразования). Но это, если вы преобразоваете, например, длинная -> короткая

Я полагаю, что просто не будет рекомендовано сделать актерский состав, так как это просто скрывает возможность ошибок. Было бы нормально после того, как вы проверили, что такой актерский состав не изменит значение для умиротворения компилятора.

Другие советы

Лучший подход:

long x = strtol(...); assert(x <= INT_MAX); return (int)x;

Тебе нужно limits.h а также assert.h

Если у вас нет доступа к boost::numeric_cast, вы можете написать простую имитацию:

template <typename T, typename S>
T range_check(const S &s) {
    assert(s <= std::numeric_limits<T>::max());
    assert(s >= std::numeric_limits<T>::min());
    return static_cast<T>(s); // explicit conversion, no warnings.
}

return range_check<int>(strtol(some_value,0,8));

На самом деле это немного чит, так как он не работает для типов назначения с плавающей запятой. min() Не то же самое для них, как и для целочисленных типов, вам нужно проверить +/- max(). Анкет Упражнения для читателя.

Независимо от того, используете ли вы Assert или какой-либо другой обращение с ошибками, зависит от того, что вы на самом деле хотите сделать с недействительным вводом.

Есть также boost::lexical_cast (вне рук я не знаю, как сделать это читать восьмиуроку) и StringStream. Прочитайте желаемый тип, а не тот тип, который имеет для него функцию библиотеки C.

Вы не видите здесь никакого предупреждения, потому что данные дата «Int» и «Long Int» на вашей платформе имеют одинаковый размер и диапазон. В зависимости от архитектуры они могут стать другими.

Чтобы защитить себя от странных ошибок, используйте проверку диапазона. Я предлагаю вам использовать std :: numeric_limits :: min/max (см.).

После проверки диапазона вы можете безопасно использовать Static_cast или C-стиль.

С другой стороны, вы можете полагаться на ту же функциональность, реализованную в классе Std :: StringStream. Преобразование с помощью Std :: StringStream будет безопасным для платформы и по умолчанию.

Большинство современных компиляторов предупреждают о преобразовании и возможном усечении в зависимости от уровня предупреждения, который вы настроили. На MSVC, который предупреждает уровень 4.

Лучшая практика - это долгое время от вашей функции и позволить вызовому коду решить, как справиться с преобразованием. За исключением этого, по крайней мере, убедитесь, что значение, которое вы возвращаете от Strtol, поместится в Int, прежде чем вернуться, как это было предложено let_me_be.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top