Given some code like :
unsigned short val;
//<some unimportant code that sets val>
How can we disable the "comparison is always false due to limited range of data type" warning from gcc?
This is using GCC 4.1.2, and so doesn't have the
#pragma GCC diagnostics construct.
I can't find a -W option to turn it off either.
I have tried doing a cast of val:
But it seems GCC is clever enough to still give the warning.
The compiler flags are -Wall, and that is it. No -Wextra.
I don't really want to remove the check - short might be 16-bits on this target, but doesn't mean it has to be. I am happy to write the check a different way though.
I want to turn -Werror on, so this warning has to go.
Unimportant code not so unimportant:
unsigned short val;
float dbValue; (actually function parameter)
val= ((unsigned short) dbValue) & 0xffff);
So if size of short changes, we will get overflow, and in anycase the range check becomes pointless anyway, and can be deleted, or more to the point applied to the float value instead.
Whilst the answers so far have helped improve the code, it would still be useful to know if there is any means to disable this warning in gcc 4.1.2 - which is what the question was.
It seems it can be done in recent releases using -Wno-type-limits
In theory there is no answer to your question: if what you intend to write is a no-op (on the particular architecture being targeted) for all possible values of
val the code can be reached with, then the compiler can warn that it is a no-op for all…
In practice, comparing
(val + 0) instead of
val may be enough to let the compiler produce the same code as it did with your original version and at the same time shut up about it.
I would recommend you write
#include <limits.h> … #if USHRT_MAX > 65535 if(val>65535) val=65535; #endif
I feel that if you were to use it without comment, it makes the intention clearer than any convoluted trick.
You could make use of conditional compilation:
#include <limits.h> unsigned short val; #if USHRT_MAX > 65535 if(val>65535) val=65535; #endif
Using the min macro :
#define min(x, y) (((x) < (y)) ? (x) : (y)) val=min(val,65535);
gets rid of the warning. So we can also use the same implementation directly
val=(val)<(65535)? val: 65535;
The trick here is that while a 16 bit integer cannot be greater than 65535, it can be 65535, and the check in this version is "is it lower than 65535
val was declared as an
unsigned short, which usually (see note) means 16-bit unsigned (0 - 65535), so your test can never be true, because
val can never be more than 2^16-1 (65535) with this compiler, and with this target architecture.
Casting it as a
long won't change anything. You may want to declare
unsigned long though.
note: as rightly implied in the comments section, the exact width of
int types depend on both the compiler and the target architecture. Wikipedia has a section on basic C data types that covers the question in greater details.