When I write C I tend to always return any error code on the stack and pass the pointer to where I want the result to go. Makes managing memory easier. The owner gets to allocate.
Example:
#define E_DIVZERO -100
int divide(float a, float b, float *result) {
if (b == 0.0) return E_DIVZERO;
*result = a / b;
}