Search code examples
cposix

How to properly check that an off_t value won't overflow when converted to size_t in C?


I need to cast an off_t variable to a size_t variable, and I want to detect if an overflow might happen. In C.

My initial attempts looks like this:

off_t fsize;
size_t len;

...

if(fsize >= 0 && fsize <= SIZE_MAX) {
   len = (size_t)fsize;
} else {
   abort();
}

However, the compiler doesn't like my comparison between a signed and unsigned types (fsize <= SIZE_MAX). I can't really make assumptions about the respective sizes of the off_t and size_t types either.


Solution

  • I can't really make assumptions about the respective sizes of the off_t and size_t types either.

    To compare mixed signed types whose comparable ranges are no clearly tied, cast to uintmax_t.


    Once code knows the signed fsize >= 0 is true, casting to a wide unsigned type like uintmax_t will certainly not narrow the fsize value and quiet the warning.

    if (fsize >= 0 && (uintmax_t) fsize <= SIZE_MAX) {
    

    If the cast to uintmax_t is unnecessarily wide, I'd expect the compiler to still emit efficient code.