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

问题描述 投票:3回答:3

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

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
}

注意

目前,我将断言分为三组,浮点数,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
c++ clang suppress-warnings
3个回答
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的值范围内。


0
投票

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


0
投票

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

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

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

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

返回最小的非正数(<= 0)。

浮点类型的最小负数是:

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.