Well I understood the fact that no value of ui can make this condition
false.
But when I replaced 0ul with 0u I didn't get the warning.When I
retained ul and compiled it on a 32bit machine ( ul == 32bits ) I
didn't get the warning either. I was just trying to understand the
significance of ul being 64 bits to trigger this warning.I should've
mentioned this in the original post.
My explanation is a bit complicated: Obviously a comparison like "0x0ul
<= ui" is useless. It might indicate a bug in your program, and that is
when compilers are supposed to give warnings.
A typical example would be
unsigned int ui;
for (ui = 10; ui >= 0; --ui) f (ui);
This is an infinite loop, which might come as a surprise to the
programmer who wrote it, and it definitely should get a warning. On the
other hand, such useless comparisons are very often not a bug,
especially when the operands are constants. For example:
#define VERSION 3 /* Could be 1, 2, 3 or 4 */
if (VERSION == 1) {
...
} else if (VERSION == 2) {
...
} else if (VERSION == 3) {
...
} else if (VERSION == 4) {
...
}
After macro substitution, all the comparisons are "useless" but there is
no bug here. So it is quite likely that a compiler doesn't give warnings
when only constants are involved.
It could be that because of the mix of unsigned int and unsigned long in
your code the compiler doesn't recognize that only constants are
involved; it might not recognize "(unsigned long) ui" as a constant
anymore, and therefore you get a warning.
There are no exact rules for warnings, every compiler does its best to
give warnings on suspicious code and give no warnings on code that works
as intended, and getting this right is difficult.