ssize_t is not standard C. It's defined in POSIX.
While it's a signed integer, whereas size_t is unsigned, I don't know
how it relates to size_t on a given implementation in terms of width.
Mixing the two doesn't seem like a good idea. At least if you want
portability or even just want to know when a mixed sum is going to overflow.
With that said, a more general fact is that artihmetic operations
involving unsigned integers only can never "overflow" in C, because the
result is always modulo N: quoting the standard: "A computation
involving unsigned operands can never overflow, because a result
that cannot be represented by the resulting unsigned integer
type is reduced modulo the number that is one greater than the
largest value that can be represented by the resulting type."
Now, except for the case of all operands being unsigned, all other
combinations would yield an "undefined behavior", as said here: "If an
exceptional condition occurs during the evaluation of an expression
(that is, if the result is not mathematically defined or not in the
range of representable values for its type), the behavior is undefined."
In short, if 'a+b' can't be represented with the resulting type (which
you call "would overflow"), then it's 'a+b (mod 2^N)' with N being the
bit width of the resulting integer type, if both a and b are unsigned.
In any other case, including your case above, it's undefined behavior.
So, the result of adding a ssize_t integer to a size_t integer is
undefined per the standard if the sum "would overflow". All you can
safely do here is test before adding.
Note that while, on many platforms, the result will effectively be
computed modulo 2^N as with unsigned operands only (because it's often
the cheapest way of doing it with many ISAs), you can't count on this
according to the standard. Not just that, but the operation itself could
well raise an exception, even though it's uncommon. So ideally, for
portable code, you should test *first* and only issue the operation if
the result "would not overflow".