Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ssize_t vs int

Code

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 

Questions

  • Which prototype should I use?
  • What types should I give to 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.

like image 586
hyde Avatar asked Oct 07 '13 12:10

hyde


People also ask

Is it better to use Size_t or int?

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.

Can you compare Size_t and int?

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.

What is Ssize_t data type?

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.

Is Ssize_t signed?

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.


2 Answers

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 C
  • ssize_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.)

like image 60
Fred Foo Avatar answered Sep 28 '22 06:09

Fred Foo


Use types in a way:

  • you don't mix signed and unsigned types together and
  • you don't truncate values from larger types while storing them in smaller types (overflow/underflow)

ssize_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).

like image 37
LihO Avatar answered Sep 28 '22 06:09

LihO