Я проверяю диапазон числовых значений с типом черт, а беззнаковые типы генерируют предупреждение.
Comparison of unsigned expression >= 0 is always true
Как отключить некоторые предупреждения в определенном диапазоне кода? Я использовал стиль GCC #pragma
с Clang, но это не работает.
Вот мой код
template<typename originT, typename destinationT>
void
assertForNumericRange(const originT value)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"assertWithReason(value >= std::numeric_limits<destinationT>::min());
assertWithReason(value <= std::numeric_limits<destinationT>::max());
#pragma GCC diagnostic pop
}
Заметка
В настоящее время я разделил утверждение на три группы: с плавающей точкой, без знака int, со знаком int. Но я хочу объединить их, если это возможно.
Я использую Xcode 5.0 beta. В командной строке он сообщает об этом:
Версия Apple LLVM
5.0 (clang-500.1.58) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.3.0
Thread model: posix
Какую версию Clang вы используете? От Руководство пользователя Clang это должно работать точно так же, как вы. Но ваши утверждения диапазона не будут работать так, как вы, вероятно, хотите, чтобы они работали:
Это первое утверждение само по себе не имеет большого смысла, если destinationT
без знака, поэтому min дает 0. Либо originT
также без знака, то это явно не отрицательно, о чем вас предупреждает компилятор. Или же originT
подписано, сравнение преобразует один или оба операнда в другие типы, например возможно преобразование value
на неподписанное (и, следовательно, положительное) представление.
Рассмотрим для примера
assertForNumericRange<signed char, unsigned long>( (signed char)-1);
Сравнения между (signed char)-1
а также unsigned long
будет продвигать -1 к unsigned long
эффективно выдавая следующие 32-битные утверждения:
assertWithReason((unsigned long)0xFFFFFFFF >= std::numeric_limits<destinationT>::min());
assertWithReason((unsigned long)0xFFFFFFFF <= std::numeric_limits<destinationT>::max());
Оба сравнения дадут истину, а -1 ясно не в диапазоне unsigned long
ценности.
Прежде всего, имейте в виду, что:
std::numeric_limits<float>::min()
вернет ноль, как
std::numeric_limits<T>::min()
возвращает наименьшее неотрицательное число для целочисленных типов, наименьшее неотрицательное число для типа с плавающей запятой
Минимальное отрицательное число для типа с плавающей точкой:
-std::numeric_limits<T>::max()
Я думаю, что вы должны сочетать разные методы / члены numeric_limits (лайк is_integer
а также is_signed
) и если заявления, а также, чтобы избавиться от ваших предупреждений. (С точки зрения эффективности) Вам не нужно беспокоиться о получении слишком сложной функции, поскольку большинство проверок будет оцениваться во время компиляции и не будет влиять на время выполнения. Фактически, если вы сможете избежать ненужных проверок во время выполнения из-за некоторых проверок, выполненных во время компиляции, ваша программа будет работать быстрее.
Вы также должны использовать std::is_same<T,U>::value
и избегайте дальнейшей проверки, если это правда.
Проверьте этот вопрос&А я только что отправил. Для меня это компилируется без предупреждений, вы должны проверить это на Clang. Возможно расширение до типов с плавающей запятой.