Re: Style question: comparison between signed and unsigned?

kwrohrer@enteract.com
Tue, 23 Sep 1997 04:17:18 -0500 (CDT)


And lo, Richard Gooch saith unto me:
> Dean Gaudet writes:
> > On Mon, 22 Sep 1997, Linus Torvalds wrote:
> > > On Mon, 22 Sep 1997, Dean Gaudet wrote:
> > > > I know this is where the warning is generated. But my claim is that this
> > > > supposedly "bad" code is forced due to the lame prototype for read().
> > > > Overloaded return values are bad.
> > > >
> > > > You could misinterpret the compiler's warning to mean you need a cast ...
> > > > but really it means you need to redesign your code :)
> > > Redesign the whole C language? Or "just" all of the library?
> > "just" all of the library. It's really what's at fault. Microsoft (or
> > IBM) got it right when they did OS/2's system api ... and win32's api also
> > does it right. The return value is always an error code, other returns
> > are passed by reference.
> Great. More junk to throw onto the stack and more things to bash the
> cache.
You would prefer read to return union { enum { OOPS=-1} oops; int val;} then?
I can think of no better way to tell the compiler about the overloading.
You could even make "val" be an unsigned int...until someone tries to set
it to MAXUINT, anyway... You could also return a struct rather than a
union, but then you'd whine about it being too big to fit in a register,
or increasing the size of the stack anyway, depending on the convention
for returned values.

Some functions in libc already take "out" parameters, by pointer; I'd
certainly rather see different notional information encoded by different
parameters, than a function returning tangled_mess_t.

> Using that model I guess we should also abandon NULL pointers
> to indicate errors...
NULL implying error is fine. But how could read--or anything which can
return 0 as a non-error--return NULL in case of error?

The actual problem here isn't the fact that an out-of-band value is
being used to indicate an error. Observe the complained-about case:

int result=read(...);
if (result==-1) return;
if (result<sizeof(something))
...

The "problem" is that the second if "looks" good, but that sizeof() is
unsigned. Here's what the compiler is thinking might happen:

* result < -1
and/or
* sizeof(something) >MAXINT

If both could happen, the compiler can't possibly do what you "mean"
with a signed, or an unsigned, comparison instruction in all cases.
So it warns you. It might be appropriate to suppress the warning
if sizeof() doesn't use its high bit (known at compile time) and
just go with a signed comparison; likewise, if I'd returned on
result<0, it could go with an unsigned comparison. But in
general, you're asking a lot when you do a signed/unsigned
comparison, and a warning really is appropriate.

I'd just as soon use the macro someone already suggested, and pray
sizeof() never returns >MAXINT...

Keith