I've got a function which I can write in one of four possible ways:
int do_or_die(int retval); int do_or_die(ssize_t retval); ssize_t do_or_die(int retval); ssize_t do_or_die(ssize_t retval);
And then it will be called with both of these ways for library functions:
written = do_or_die(write(...)); // POSIX write returns ssize_t printed = do_or_die(printf(...)); // printf returns int
written
and printed
?I want to have the most robust and standard code, while still having just one do_or_die
function.
I am using C99 in this case, but if answer is different for C11, then I'd like to know that too, for future.
When writing C code you should always use size_t whenever dealing with memory ranges. The int type on the other hand is basically defined as the size of the (signed) integer value that the host machine can use to most efficiently perform integer arithmetic.
It is okay to compare a size_t value with an int value, the int value will be implicitly converted to unsigned type. Some compilers will issue a warning when you mix signed and unsigned types in comparisons.
In short, ssize_t is the same as size_t , but is a signed type - read ssize_t as “signed size_t ”. ssize_t is able to represent the number -1 , which is returned by several system calls and library functions as a way to indicate error. For example, the read and write system calls: #include <sys/types.
ssize_t is not a signed size_t . It is only guaranteed to support a signed value of -1, and while it might work on Posix, it is an unsigned type on Windows.
There's no guarantee in the POSIX standard that sizeof(int) >= sizeof(ssize_t)
, nor the other way around. Typically ssize_t
is larger than int
, but the safe and portable option in C99 is to use intmax_t
instead for the argument and the return value.
The only guarantees you have wrt. the relationship between int
and ssize_t
are:
int
can store values of at least the range [-2^15 ... 2^15-1] per ISO Cssize_t
can store values of at least the range [-1 ... 2^15-1] per POSIX (see _POSIX_SSIZE_MAX
).(Interestingly, there isn't even a guarantee that ssize_t
can store the negative counterparts of its positive range. It's not a signed size_t
, but a "size type" with an error value.)
Use types in a way:
signed
and unsigned
types together andssize_t
might be an alias for int
, yet it is not standard C and might be environment specific.
If your program will run in specific environment, check whether sizeof(ssize_t) <= sizeof(int)
and use int
. Otherwise, use some other type T
where sizeof(T)
is greater or equal than both sizeof(int)
and sizeof(ssize_t)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With