Re: SOLUTION (Re: Style question: comparison between signed and unsigned?)

Tom Dailey (dailey@deltanet.com)
Sat, 27 Sep 1997 09:55:24 -0700


Andrew G. Morgan wrote:
>
> Gerard Roudier wrote:
> > > Your solution is close to being correct, POSIXwise. The completely
> > > "compliant" way of doing this is
> > >
> > > ssize_t read_return_value;
> > > size_t nr_of_bytes_read;
> ....
> > > nr_of_bytes_read = (size_t) read_return_value;
> >
> > Your cast is just stupid in my opinion.
> > Your are just assuming that the called function only returns > 0 when it
> > does not return -1.
>
> Since everyone and his dog has chipped in here and reasonably convincing
> arguments have been banded about, perhaps we can have some
> concensus/agreement to differ and move on?
>
> "Strictly" speaking, I think the gcc crowd have done a good job of trying to
> make sense of 'C'. Appendix A6.5 of K&R II casts a murky shadow over this
> whole discussion: promotion of ints to unsigneds and their architecture
> dependent behavior for int<->long conversions.
>
> My take on this is that sizeof() should return something signed and not
> unsigned since who ever made a structure half the size of the address space?
> But that's my take and a lot of my elders and betters got to make the
> choice without ever asking me ;^) [It seems that Ted and I would have
> written the 'C' spec differently!]
>
> Regarding 'read()', POSIX and ISO are simply different..
>
> POSIX: int read(int fd, void *buf, unsigned int nbytes)
> ISO: ssize_t read(int fd, void *buf, size_t nbytes)
>
> the latter attempts to accomodate the possibility that the address space is
> larger than what can be held in an unsigned int by introducing some new
> types. When you look at the POSIX prototype, you do wonder what is supposed
> to happen when nbytes is larger than the maximum value that an int can hold
> (namely, how does its return value report such a large read?). In reality,
> no-one is ever going to find they can read that much data in a single read
> but the whole issue is one of principle and that means people want to argue
> about it!
>
> On this point, I realized that I needed to take a second look and
> 'understand' what a ssize_t is.. Before this discussion began, I have to
> confess that I had assumed it was a 'signed'-number with one-bit less of a
> positive range than the 'size_t'. However, thinking about it in this
> context and trying to make some sense of the aside on p386 of Lewine's POSIX
> book (definition for read()), it would seem that it is more properly
> described as exactly the same as a size_t but with indiviual value(s)
> reserved for errors. (If this is wrong, I would be grateful for a pointer to
> the actual definition..) In the ISO convention, then, comparing the return
> value of read with a negative integer _is_ worthy of a comment from gcc
> -Wall..
>
> The bottom line is that POSIX and ISO read()'s are different and, given the
> implicit arithmetic conversions of 'C', we are just wandering around in
> circles trying convince each other that the better one is the one we prefer
> to use. Despite the fact that all the manuals indicate that read uses ISO
> conventions, a look at the kernel source indicates that kernel has an
> independent notion of the prototype for read (2.0.31pre9):
>
> asmlinkage int sys_read(unsigned int fd,char * buf,int count)
>
> [with int -> long for 64 bit machines] So what has resulted is different
> people "knowing" they are right about their own opinion. :^)
>
> Perhaps we should agree (or defer to Linus) on which convention we are going
> to support and tidy up the respective source? Whatever, I think it is clear
> that this is likely to be an unpopular "feature" of gcc so an _extra_
> command line option should be available to turn it off (without losing all
> the other -Wall benefits).
>
> [That was a lot longer than I had planned. But I don't anticipate emailing
> about this again...]
>
> Cheers
>
> Andrew
> --
> Linux-PAM, libpwdb, Orange-Linux and Linux-GSS
> http://parc.power.net/morgan/index.html
>
> --
> Linux-PAM, libpwdb, Orange-Linux and Linux-GSS
> http://parc.power.net/morgan/index.html

I am fascinated by your distinction between "ISO" and "POSIX", since,
as far as I know, these are the same. POSIX is defined by the standards
document designated ISO/IEC 9945-1 (ANSI/IEEE Std 1003.1, Second
edition, 1996-07-12), and entitled "Information Technology - Portable
Operating System Interface (POSIX) - Part 1: System Application Program
Interface (API) [C Language]." If there is another, overriding standard
that defines POSIX, I would be very interested in knowing about it.

Incidentally, in the above-mentioned document, the read() function's
prototype is given (sect. 6.4.1.1) as

ssize_t read ( int fildes, void* buf, size_t nbyte );

Regards,
Tom Dailey