如何让Clang忽略特定块中的特定警告?

时间:2013-06-20 05:09:42

标签: c++ clang suppress-warnings

我正在检查类型特征的数值范围,而无符号类型会生成警告。

Comparison of unsigned expression >= 0 is always true

如何在特定代码范围禁用某些警告?我在Clang中使用了GCC样式#pragma,但这不起作用。 这是我的代码。

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
}

注意

目前,我将断言分为三组,浮点数,unsigned int,signed 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 个答案:

答案 0 :(得分:1)

你使用的是哪个版本的Clang?从the Clang User Manual起,它应该像你一样工作。但是你的范围断言不会像你希望的那样工作:

第一个断言本身没有多大意义,如果destinationT是无符号的,那么min给出0. originT也是无符号的,那么它显然不是负数,编译器会发出警告你大概。或originT已签名,比较会将操作数中的一个或两个转换为其他类型,例如可能将value转换为无符号(因此为正)的表示。

考虑例如

 assertForNumericRange<signed char, unsigned long>( (signed char)-1);  

(signed char)-1unsigned 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的值范围内显然

答案 1 :(得分:0)

首先,请注意浮点类型,例如

std::numeric_limits<float>::min()

返回minimum positive normalized value(&gt; 0),而对于整数类型

std::numeric_limits<T>::min()

返回最小的非正数(&lt; = 0)。

浮点类型的最小负数为:

-std::numeric_limits<T>::max()

我认为你必须结合不同的numeric_limits methods/members(如is_integeris_signed)和if语句,以消除你的警告。 (从效率的角度来看)您不必担心获得过于复杂的功能,因为大多数检查将在编译时进行评估,并且不会影响执行时间。实际上,如果由于在编译时进行了一些检查,你可以在运行时避免一些不必要的检查,那么你的程序会更快。

您还应该使用std::is_same<T,U>::value,并且如果确实如此,请避免进一步检查。

答案 2 :(得分:0)

检查this Q&A I just posted。对我来说,它编译没有警告,你应该在Clang上检查它。可以扩展到浮点类型。