Re: ssize_t and size_t



Nate Eldredge wrote:
kid joe <spamtrap@xxxxxxxxxxxxxxxx> writes:

Hi all,

I was thinking about interfaces like this one for Unix read

ssize_t read(int fd, void *buf, size_t count);

(I know that read isnt an ISO C function, but the question is nothing to
do with read, just the function interface).

The return value is -1 in case of error, or an integer between 0 and count
giving the number of bytes read into buf.

This seems like a poor choice to me.... If I pass SIZE_MAX for count, then
there's no way of distinguishing between an error (-1) and a successful
read of ((size_t) -1) bytes.

There is, actually: set `errno' to 0 beforehand and check afterwards to
see if it is nonzero. Not the most convenient thing, but your only
option if you might pass SIZE_MAX as an argument.

However, better would be not to do that at all, and that's usually the
officia stance: don't do that. For instance, my system's man page for
`read' says that any value for `count' larger than INT_MAX is
errnoneous, and read() returns -1 and sets errno to EINVAL. So if
`count' is SIZE_MAX (typically larger than INT_MAX), you know ahead of
time that the read() is going to fail.

Aside: This is due to the fact that read() hearkens from C's "everything an int" days long ago. The "count" parameter was originally an int, therefore it was not possible to pass a count larger than INT_MAX, and therefore a negative (int) return value unquestionably meant an error. However, when ANSI created size_t, the POSIX folks went back and changed many of their types to size_t, which enabled passing larger values in many cases because size_t was unsigned; however, the return value for many other functions needed to accommodate negative values so it was changed to ssize_t (which they invented for the purpose and is not part of ANSI/ISO C).

The result is what Nate explains: you can't meaningfully pass a value larger than SIZE_MAX/2 to read(), even though the parameter has type size_t -- and most implementations will check for that case and immediately return an error if you try it. Implementations with a 64-bit size_t and a 32-bit int may also disallow passing a count greater than INT_MAX, even though that would be meaningful.

Any time you see a return value of ssize_t, expect this limitation to rear its ugly head.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Isaac Jaffe
.



Relevant Pages

  • Re: Debugging memory leaks
    ... Nate Eldredge writes: ... Hmm. ... On such implementations, assuming `int' was also 16 bits, did an ... If int is 16 bits, ...
    (comp.lang.c)
  • Re: MprAdminInterfaceEnum
    ... > Trying to enumerate interfaces on RRAS. ... the enumeration cannot be continued. ... > public static extern int MprAdminInterfaceEnum( ...
    (microsoft.public.dotnet.framework.interop)
  • Giant packets on a 10Gig interface
    ... switchport trunk encapsulation dot1q ... The 10Gb interfaces on each end of this link are reporting a large number of giants when I do a show int. ... input packets with dribble condition detected ...
    (comp.dcom.sys.cisco)
  • Re: Object orientation.....
    ... void *draw(unsigned char *rgb, int width, int height, int x, int y); ... Thus you build your object from interfaces. ...
    (comp.lang.c)
  • How to get all IP Addresses on AIX using C++
    ... I have been trying to get all ip addresses from all interfaces, ... int main ... printf("There is trouble of sock!! ... int rval = ioctl(sock, SIOCGIFADDR, ifr); ...
    (comp.unix.programmer)