How to silence a specific "meaningless unsigned comparison with a null" warning?

Suppose I have a function like:

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

Assuming that I have warnings configured accordingly, if some_typedef is unsigned, I will get a warning that there is a meaningless comparison of the unsigned type with 0. Of course, this is true, and it makes sense.

However, let's say that I want the check against zero to be in the code for one or several possible reasons, for example:

  • While borders will always be compile-time constants, they may be something that can change (and macros may not "live" very close to the function). For example, boundaries can be specified by passing options to the compiler.
  • I would like to protect myself from a later typedef change to a signed type, since it is possible that every use of typedef cannot be carefully checked when changing it.

Is there a decent, reasonably portable way to drown out a warning here without shutting it down completely?

Something that relies on the STATIC_ASSERT () functionality that is available to me would be acceptable if it were reasonable. I'm fine with a compilation violation if the type changes to make someone look at the code. But it may be important to note that typeof is not what I have in all the compilers I am aiming for.

I am specifically looking for C-language solutions, so templates are not needed here ...

+8
c warnings
source share
4 answers

If some_typedef not known that it is not specified or signed, I think you are very unlucky.

If you know in advance that some_typedef not specified, you can simply use

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

Or in this case you can use my preferred version:

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

Edit: I assume that if some_typedef not known to have a special signature, then UPPER_BOUND and LOWER_BOUND should be positive. Otherwise, you will have very bad results from some_typedef , which will be promoted to unsigned. Thus, you can always safely use:

  return ((uintmax_t)val-LOWER_BOUND <= UPPER_BOUND-LOWER_BOUND); 
+6
source share

This is usually controlled by pragmas. For MSVC, you have #pragma warning , and for GCC, you have diagnostic pragmas (which admittedly does not allow fine-grained warning management like MSVC, but that's all you have).

Both allow the push / pop mechanic to mechanically modify warnings for only a few lines of code.

+2
source share

I came up with a fairly simple and straightforward solution. Copying the lower bound of the 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 assembly, the compiler can still easily get rid of comparing invariants (although I will have to check).

+1
source share

Instead of trying to silence the warning, why not do something about it and avoid typing in the first place? You can do overloads to handle specific cases, and by avoiding masking warnings, making it more clear that you are handling the cases you are dealing with. In my experience, this forces you to test new code instead of masking things that might happen in the future (for example, a sudden change in data types, and then having to deal with values โ€‹โ€‹that are mysteriously unable to lie in expected ranges).

0
source share

All Articles