I know this isn’t going to shed light on the “social problem issue” I mentioned in my last post. That subject has been postponed, as I am currently working on PDCLib. That project is actually where I first got into close contact with the greatness of POSIX programming and initiated my boiling disappointment with this “standard”.
Take the output of man 2 write, for example. Just look at the synopsis for a moment:
ssize_t write(int fd, const void *buf, size_t count);
Notice something? Hint: There’s one ’s’ too many. We’ll come to that.
The function write()
is supposed to write a number of bytes - specified by the parameter count
- to a file handle. As count
is of type size_t
(an unsigned type), that could be anywhere from 0
to SIZE_MAX
bytes. Most importantly, it could be more than INT_MAX
bytes. No harm done so far.
Let’s have a look at the return code of the function.
On success, the number of bytes written is returned (zero indicates nothing was written). On error, -1 is returned, and errno is set appropriately.
OK… wait. D’uh? Did you see that? I put in an unsigned value, and get as return that value on success… or a -1 on error. How can that be?
Easy: They invented a cool new data type, ssize_t
. If you dig through man unistd.h
to man types.h
, you will eventually find it defined as a type used “for a count of bytes or an error indication”, conventiently named in such a way that it’s easily confused with the real thing (size_t
).
So here is a magic type which can store the value range of a size_t
and a -1
. Sadly, it can’t, as you could easily determine with five lines of C code and a sizeof()
: ssize_t
and size_t
have the same size. Means, there is no difference in the returned value between a max-sized buffer and an error condition.
We could discuss the probability now of someone wanting to write SIZE_MAX
of data to a file handle at once. The point is, write()
does allow to do so, without a note of warning that you will get a -1
as return from the function no matter what. This might never lead to errors in the wild, which might be the reason why the POSIX people felt they could get away with it (”WONTFIX - works for me”). But proper domain testing will stumble over this. I can only assume the POSIX people have never heard of domain testing.
An ugly sideeffect of this is that comparing the return value of write()
with count
will give you a signedness mismatch warning. But I *know* that the POSIX people don't believe in compiler warnings…