comparing unsigned long and unsigned int

S

sridhar

#include <stdio.h>
int main(){
unsigned int ui = 0;
if(0x0ul <= ui){
printf("less eq\n");
}
}

On my system unsigned long is 64 bits and unsigned int is 32.The
compiler gives a warning

warning: comparison is always true due to limited range of data type

What is happening here?
Thanks
sridhar
 
J

Jonathan Adams

#include <stdio.h>
int main(){
unsigned int ui = 0;
if(0x0ul <= ui){
printf("less eq\n");
}
}

On my system unsigned long is 64 bits and unsigned int is 32.The
compiler gives a warning

warning: comparison is always true due to limited range of data type

The compiler is letting you know that 0ul <= ui is always true, since
unsigned numbers can't be negative.

Cheers,
- jonathan
 
K

Keith Thompson

#include <stdio.h>
int main(){
unsigned int ui = 0;
if(0x0ul <= ui){
printf("less eq\n");
}
}

On my system unsigned long is 64 bits and unsigned int is 32.The
compiler gives a warning

warning: comparison is always true due to limited range of data type

You're not getting the warning because you're comparing ui to an
unsigned long; you're getting the warning because you're comparing ui
to zero.

Think about it. ui is unsigned. For what possible values of ui would
(0x0ul <= ui) or, more simply, (ui >= 0), be false?
 
S

sridhar

Keith Thompson said:
You're not getting the warning because you're comparing ui to an
unsigned long; you're getting the warning because you're comparing ui
to zero.

Think about it. ui is unsigned. For what possible values of ui would
(0x0ul <= ui) or, more simply, (ui >= 0), be false?

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.
 
K

Keith Thompson

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.

Unless I'm missing something obvious, it's probably just an odd quirk
of the compiler you're using. I can't think of any reason why
changing 0x0ul to 0x0u should inhibit the warning. (You used the same
command-line options in both cases, right?)
 
C

Christian Bau

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.
 
J

J. J. Farrell

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.

There is no significance in this case. It's a 'quality of implementation'
issue. It appears that when the compiler is "thinking about" the two
operands having a different size, it notices that the comparison is
always true and warns you about it. When they're the same size, it
doesn't notice (or doesn't choose to warn you).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top