How to make Clang to ignore specific warning in sp

2019-05-14 00:08发布

问题:

I am checking numeric value range with type traits, and unsigned types generate warning.

Comparison of unsigned expression >= 0 is always true

How to disable some warning at specific code range? I used GCC style #pragma with Clang but this doesn't work. Here's my code.

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
}

Note

Currently, I divided the assertion into three groups, floating-point, unsigned int, signed int. But I wish to integrate them into one if possible.

I am using Xcode 5.0 beta. In command-line, it reports this: Apple LLVM version

5.0 (clang-500.1.58) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.3.0
Thread model: posix

回答1:

Wich version of Clang are you using? From the Clang User Manual it should work exaclty the way you did. But your range assertions won't work the way you probably want them to work:

That first assertion itself does not make much sense, if destinationT is unsigned, so min gives 0. Either originT is unsigned as well, then it's clearly not negative, wich is what the compiler warns you about. Or originT is signed, the comparison will convert one or both of the operand to other types, e.g. possibly converting value to an unsigned (and thus positive) representation.

Consider for example

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

The comparisons between (signed char)-1 and unsigned long will promote the -1 to unsigned long, effectively giving following assertions for 32bit long:

assertWithReason((unsigned long)0xFFFFFFFF >= std::numeric_limits<destinationT>::min());
assertWithReason((unsigned long)0xFFFFFFFF <= std::numeric_limits<destinationT>::max());

Both comparisons will give true, while -1 is clearly not in the range of unsigned long's values.



回答2:

Check this Q&A I just posted. For me it compiles without warnings, you should check it on Clang. Extension to floating point types is possible.



回答3:

First of all, be aware that for floating point types, e.g.

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

returns the minimum positive normalized value (>0), while for integer types

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

returns the smallest non positive number (<=0).

Minimum negative number for a floating point type is:

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

I think you have to combine different numeric_limits methods/members (like is_integer and is_signed) and if statements, also to get rid of your warnings. (From the efficiency point of view) You do not have to worry of getting a too complicated function, as most of the checks will be evaluated at compile time and will have no influence on the execution time. In fact, if you can avoid some unnecessary checks at running time because of some checks done at compile time, your program will be faster.

You should also use std::is_same<T,U>::value, and avoid any further check if that is true.