3

I got a warning when compiling my code that calls write()

warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

Here is the definition of write():

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

RETURN VALUE
   On success, the number of bytes written is returned  (zero  indicates
   nothing  was  written).   On  error, -1 is returned, and errno is set
   appropriately.

This just looks strange to me. Suppose ssize_t is int and I ended up writing something big (> 2GB). I can't just use a comparison of the returned value of write() vs count, can I?

(Edit: maybe I should write my question properly: What would be the right way to use write() without getting warning nor running into a situation that count == -1 after sign conversion? Yes, I know it is undefined behavior)

some user
  • 876
  • 1
  • 12
  • 26
  • 2
    Note: `ssize_t` is POSIX, not in standard C. `size_t` is. – Sourav Ghosh Feb 08 '16 at 19:52
  • 1
    If `ssize_t` is an `int` then you're on a 32 bit OS which most likely doesn't support files > 2GB. In that case you'd need a different API - see for example [this question](http://stackoverflow.com/questions/4003405/32-bit-windows-and-the-2gb-file-size-limit-c-with-fseek-and-ftell). – Kenney Feb 08 '16 at 19:53
  • @SouravGhosh: As much as `write` is not standard C either. What is your point? – too honest for this site Feb 08 '16 at 20:11

1 Answers1

7

The return value is a signed type to allows the return value of -1 to indicate failure.

From http://linux.die.net/man/2/write:

On success, the number of bytes written is returned (zero indicates nothing was written). On error, -1 is returned, and errno is set appropriately.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    In other words, it steals 50% of the output range to act as a success flag . I'm sure it seemed like a good idea at the time – M.M Feb 08 '16 at 20:25
  • @M.M I doubt someone would ever write even a half of `size_t` at a time. You probably won't even be able to allocate that much of contiguous memory. – Alex Skalozub Feb 08 '16 at 20:53
  • @M.M, they could have used a return value of 1 for success and -1 for failure. Hindsight. I wonder whether it ever returns a number that is less than `count`? What would that signify -- half success?? – R Sahu Feb 08 '16 at 20:58
  • 1
    @RSahu writing into socket might return less than `count` if there's currently not enough space left in send buffer, so only part of data was written. You may then send the rest in subsequent call. – Alex Skalozub Feb 08 '16 at 21:07
  • @AlexSkalozub, thanks for the clarification. It makes sense. So, it is half success :) :) – R Sahu Feb 08 '16 at 21:09
  • IMO, a better design is to return the errno and use a separate parameter to return bytes written. I never liked the way errno is checked. – some user Feb 08 '16 at 22:02
  • @someuser additional parameter would take more stack (or waste a register, depending on ABI). So resource-wise it is a worse design. Windows uses something like that though ;) – Alex Skalozub Feb 09 '16 at 11:01