Search code examples
ccastingtypedefunsignedsigned

Does C provide an operator to check the signedness of a type?


If I'm using a library which currently uses a particular numeric type alias, e.g.

typedef uint32_t library_type;

void library_function(library_type x);

How would I ensure that code which needs to pass in a value from a different type remains correct, even if the library changes its typedef?

uint64_t x = get_some_number();

// …need checks here…

library_function((library_type)x);

I could add the following checks:

assert(sizeof library_type >= sizeof uint32_t);
assert(x <= UINT32_MAX);

The second check would ensure the value I get fits within the range of the current library_type. The library author does not provide a LIBRARY_TYPE_MAX definition, so the first check tries to guard the second, in case library_type were to change for whatever reason when the code is compiled in the future.

That first check would catch if library_type were change to e.g. int8_t, but what if the library_type were changed to an int32_t instead? It's still the right "size" but the range is still less than what I am checking!

Does the C language provide an operator that introspects the signedness of a type, in the same way that sizeof lets me know the width? Is there any other way to make sure my cast to library_type will only be reached if it is correct?


Solution

  • Yes, the relational operators combined with cast operator. For example:

    _Bool TYPE_is_signed = ((TYPE)-1 < 0);
    

    Or as an assertion:

    assert((TYPE)-1 < 0); // Require that TYPE is signed
    assert((TYPE)-1 > 0); // Require that TYPE is unsigned