Как заставить Clang игнорировать конкретное предупреждение в конкретном блоке?
Я проверяю диапазон числовых значений с типом черт, а беззнаковые типы генерируют предупреждение.
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
3 ответа
Какую версию 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
ценности.
Проверьте это вопросы и ответы, которые я только что опубликовал. Для меня это компилируется без предупреждений, вы должны проверить это на Clang. Возможно расширение до типов с плавающей запятой.
Прежде всего, имейте в виду, что:
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
и избегайте дальнейшей проверки, если это правда.