Skip to content

Instantly share code, notes, and snippets.

@hbobenicio
Created May 30, 2021 19:52
Show Gist options
  • Save hbobenicio/bd18f03847b584dcded0114dac3cfa31 to your computer and use it in GitHub Desktop.
Save hbobenicio/bd18f03847b584dcded0114dac3cfa31 to your computer and use it in GitHub Desktop.
A Result type example for C
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#define OUTCOME_SUCCESS 0
typedef double DivResultOk;
// TODO For a generic error handling, you coud add a polimorphic interface here. This could help for generec error handling and error chaining.
// TODO Downcasting could be a challenge, but still possible.
typedef const char* DivResultErr;
// Tagged union
typedef struct {
enum {
DIV_OUTCOME_SUCCESS = OUTCOME_SUCCESS,
DIV_OUTCOME_ERR_DIV_BY_ZERO,
DIV_OUTCOME_ERR_OVERFLOW,
DIV_OUTCOME_ERR_OVERFLOW2,
// other errors here...
} outcome;
union {
DivResultOk value;
DivResultErr err;
};
} DivResult;
static DivResult divide_by(int x, int y) {
if (y == 0) {
return (DivResult){
.outcome = DIV_OUTCOME_ERR_DIV_BY_ZERO,
.err = "divide_by: cannot divide by zero",
};
}
if (x > 1000 || y > 1000) {
return (DivResult){
.outcome = DIV_OUTCOME_ERR_OVERFLOW2,
.err = "divide_by: overflow: numbers too high",
};
}
return (DivResult){
.outcome = DIV_OUTCOME_SUCCESS,
.value = (double) x / y,
};
}
int main() {
{
int x = 10;
int y = 0;
DivResult result = divide_by(x, y);
if (result.outcome != OUTCOME_SUCCESS) {
fprintf(stderr, "error: %s\n", result.err);
} else {
printf("ok: %d / %d == %lf\n", x, y, result.value);
}
}
{
int x = 10;
int y = 1001;
DivResult result = divide_by(x, y);
switch(result.outcome) {
case OUTCOME_SUCCESS:
// noop
break;
case DIV_OUTCOME_ERR_DIV_BY_ZERO:
case DIV_OUTCOME_ERR_OVERFLOW:
fprintf(stderr, "error: %s\n", result.err);
break;
default:
fputs("error: assertion failure: unrecognized error on DivResult outcome.\n", stderr);
assert(false);
}
printf("ok: %d / %d == %lf\n", x, y, result.value);
}
{
int x = 10;
int y = 5;
DivResult result = divide_by(x, y);
if (result.outcome != OUTCOME_SUCCESS) {
fprintf(stderr, "error: %s\n", result.err);
} else {
printf("ok: %d / %d == %lf\n", x, y, result.value);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment