There are different ways to design it, but a simple version could be a function that takes 2 operands and 1 result pointer as inputs, and returns boolean (true if success, false if it overflowed):
bool SafeAddIntInt(int32_t x, int32_t y, int32_t *r);
so the caller could say
int32_t result;
if (SafeAddIntInt(x, y, &result)) {
// do something with result
} else {
// handle overflow
}
An even simpler version could just abort on over/underflow.