Re: ssize_t and size_t
- From: Stephen Sprunk <stephen@xxxxxxxxxx>
- Date: Thu, 21 May 2009 13:20:37 -0500
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
.
- References:
- ssize_t and size_t
- From: kid joe
- Re: ssize_t and size_t
- From: Nate Eldredge
- ssize_t and size_t
- Prev by Date: Re: static inline functions and gcc
- Next by Date: Re: Some language not implemented in C?
- Previous by thread: Re: ssize_t and size_t
- Next by thread: Re: ssize_t and size_t
- Index(es):
Relevant Pages
|