我正在检查类型特征的数值范围,而无符号类型会生成警告。
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
答案 0 :(得分:1)
你使用的是哪个版本的Clang?从the Clang User Manual起,它应该像你一样工作。但是你的范围断言不会像你希望的那样工作:
第一个断言本身没有多大意义,如果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
的值范围内显然不。
答案 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_integer
和is_signed
)和if语句,以消除你的警告。 (从效率的角度来看)您不必担心获得过于复杂的功能,因为大多数检查将在编译时进行评估,并且不会影响执行时间。实际上,如果由于在编译时进行了一些检查,你可以在运行时避免一些不必要的检查,那么你的程序会更快。
您还应该使用std::is_same<T,U>::value
,并且如果确实如此,请避免进一步检查。
答案 2 :(得分:0)
检查this Q&A I just posted。对我来说,它编译没有警告,你应该在Clang上检查它。可以扩展到浮点类型。