How to silence a particular “pointless comparison of unsigned with zero” warning?

后端 未结 4 1454
無奈伤痛
無奈伤痛 2021-01-18 01:59

Suppose I have a function like the following:

#define LOWER_BOUND 0
#define UPPER_BOUND 42

int is_value_in_range( some_typedef val)
{
    return ((LOWER_BOU         


        
相关标签:
4条回答
  • 2021-01-18 02:11

    If some_typedef is not known to be unsigned or signed, I think you're pretty much out of luck.

    If you know in advance that some_typedef is unsigned, you could just use

    #if LOWER_BOUND > 0
        return ((LOWER_BOUND <= val) && (val <= UPPER_BOUND));
    #else
        return ((val <= UPPER_BOUND));
    #endif
    

    Or in this case, you could use my preferred version:

        return (val-LOWER_BOUND <= UPPER_BOUND-LOWER_BOUND);
    

    Edit: I'm going to assume if some_typedef is not known to be of particular signedness, then UPPER_BOUND and LOWER_BOUND must both be positive. Otherwise you would have very wacky results from some_typedef getting promoted to unsigned. Thus, you could always safely use:

        return ((uintmax_t)val-LOWER_BOUND <= UPPER_BOUND-LOWER_BOUND);
    
    0 讨论(0)
  • 2021-01-18 02:20

    Rather than trying to silence the warning, why not do something about it and avoid the typedef in the first place? You can make overloads to handle specific cases and by avoiding the masking of warnings your more explicitly declaring that you're handling the cases you're dealing with. In my experience, that tends to force you to test new code instead of masking things which might happen in the future (like suddenly changing data types and then having to deal with values mysteriously failing to lie in expected ranges).

    0 讨论(0)
  • 2021-01-18 02:26

    I came up with a pretty simple and straight forward solution. Copying the lower bound to a variable causes the compiler to stop complaining:

    #define LOWER_BOUND 0
    #define UPPER_BOUND 42
    
    int is_value_in_range( some_typedef val)
    {
        some_typedef lowerbound = LOWER_BOUND;
    
        return ((lowerbound <= val) && (val <= UPPER_BOUND));
    }
    

    I expect that in an optimized build, the compiler will still be able to easily get rid of the invariant comparison (I'll have to verify, though).

    0 讨论(0)
  • 2021-01-18 02:36

    That's usually controlled by pragmas. For MSVC, you have #pragma warning and for GCC you have diagnostic pragmas (which admittedly don't allow for as fine-grained control over warnings as MSVC, but that's all you have).

    Both allow for push/pop mechanics to only change the warnings for a few lines of code.

    0 讨论(0)
提交回复
热议问题