IMHO, C really should just standardize the standard checked overflow intrinsics. It's a lot saner than having users try to guess the correct overflow matching pattern (it's worse for multiplication), and many architectures make detecting overflow pretty trivial.
I think I might be missing the intent of this exercise, but that expression risks overflow (and undefined behaviour) when b is not equal to zero, right?
You might be interested in a related challenge: write a function in standard C++ that returns the difference between any pair of int32_t values. This cropped up on StackOverflow. It's tricky enough to trip up the incautious.
The representation of signed numbers is implementation-defined, not undefined.