C size_t and ssize_t negative value

In the first case you're assigning to an unsigned type - a. In the second case you're using the wrong format specifier. The second specifier should be %zd instead of %zu.


First of all you should check the actual size of the two types. Something like the following snippet should do:

#include <stdio.h>
#include <unistd.h>

int main() {
  printf( "sizeof(  size_t ) = %d bytes\n",(int) sizeof( size_t) );
  printf( "sizeof( ssize_t ) = %d bytes\n",(int) sizeof( ssize_t) );
  return 0;
}

I get (64bit Linux, GCC v7.2) "8 bytes" in both cases, which is the same as long int and long long int, the maximum CPU-native integer value.

When the sizes are the same (and they should always be), size_t can have "2x larger absolute values" than ssize_t which, in turn, can have signed (that's either positive or negative) values.

If they were different, then the larger one would be ... larger and could thus accommodate for larger values.

But in the end, ssize_t and size_t are two different types used to "talk" about sizes, lengths, amounts of memory and so on.

The former is just ditching 1 bit for the value in order to gain the sign needed to signal some sort of error.

Finally, the two types are not interchangeable, not always at least. When the size can go past 2^63 bytes/items the difference is clear. size_t won't overflow while ssize_t will.

Under "normal" circumstances you can cast from one to the other one. For the cases I mentioned earlier, you should never mix them.

Just as a reference, both strlen() and malloc() use size_t, while both read() and readv() use ssize_t.

So, ssize_t is not the signed version of size_t as there are values in ssize_t that cannot be mapped on a size_t (like -1) and viceversa. And library functions either use one type or the other one.

Then, to your questions, the two numbers you see differ by 5 units, that's exactly what you'd expect. What you see is the value of those two variables when seen as unsigned long. Try printing them as signed long (%ld) instead so you can still see the sign.

Tags:

C

Size T