Как заставить 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и избегайте дальнейшей проверки, если это правда.

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