Looking for review of design strategy of using a struct to return the functional result and error status.  Your experience of how my design approach may succeeded or failed is especially welcomed.In constructing a library of functions, I've tried various error handling approaches, none completely satisfactory and was about to embark on this 5th strategy. (1-4 below.) Identifying any pitfalls or referencing any existing like-designed specification is sought.Return result as a struct bundled with the status.Below is a small portion of a much larger conversion set of functions.  The style/correctness of the function bodies is primarily illustrative of how functions may construct the combined struct result.  In main(), one example use the returned structures value and status. The next just uses the value, showing a functional usage.#include <errno.h>#include <math.h>#include <stdio.h>#include <stdlib.h>typedef struct {  errno_t error;  double retval;} e_double_type;typedef struct {  errno_t error;  unsigned retval;} e_unsigned_type;e_double_type string_to_double(const char *src) {  char *endptr;  errno = 0;  e_double_type y = { 1, strtod(src, &endptr) };  if (endptr == src) return y;  if (errno && fabs(y.retval) > 1.0) return y;  y.error = 0;  return y;}e_unsigned_type longlong_to_unsigned(long long x) {  e_unsigned_type y = { 1, 0 };  if (x < 0) return y;  if (x > UINT_MAX) {    y.retval = UINT_MAX;    return y;  }  y.retval = (unsigned) x;  return y;}int main(void) {  // Error status and value   e_double_type y = string_to_double(123);  printf(%d %le\n, y.error, y.retval);  // Just value - status not of concern  // e_unsigned_type variable not needed  printf(%u\n, longlong_to_unsigned(123456789012345).retval +      longlong_to_unsigned(12345).retval);  return 0;}Typical other methods to receive a function result and error status include which I have tried.Global errno: errno = 0;char *endptr;long num = strtol(some_string, &endptr, 10);if (errno) Handle_RangeError();Return special value:int ch = fgetc(stdin);if (ch == EOF) Handle_Problem();Pass address of error status and return result:int status;y = foo(x, &status);if (status) Handle_fooFailure();Pass address to store result and return error status:FILE *stream;errno_t status = fopen_s(&stream, filename, r);if (status) Handle_OpenFailure();The above methods, except #2, fail to keep the result and status together.  #2 requires a wider return type that is often not available.  The program model of using a function, where the parameters are only the inputs, and the result is the output is very appealing.  
Returning result and error status for number type conversions
c;converting;error handling;library