Skip to content

Instantly share code, notes, and snippets.

@alepez
Last active December 22, 2021 16:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alepez/3c414085c5136ffea2477f54e50f0e8c to your computer and use it in GitHub Desktop.
Save alepez/3c414085c5136ffea2477f54e50f0e8c to your computer and use it in GitHub Desktop.
#include <stdio.h>
// a is an input parameter
// b is an input parameter
// return the result
int divide_1(int a, int b) {
return a / b;
}
// But what if we need to return an error code?
// Here we need to handle edge cases, like
// where b == 0, because division by zero is invalid
int divide_2(int a, int b) {
if (b == 0) {
// Returning zero here is not the right thing to do, because zero
// can also be a valid result (e.g. when a=0)
// Also, we cannot return something like infinite, because the type int do not
// have a value for infinite.
return 0;
}
return a / b;
}
// Many developers use to do this instead:
// Every function which can fail returns an error code
// Results are written in the so called "output parameters"
typedef enum {
ERROR_SUCCESS = 0,
ERROR_INVALID_ARGUMENT,
} Error;
// a is an input parameter
// b is an input parameter
// c is an output parameter
// return an error code
Error divide_3(int a, int b, int* c) {
if (b == 0) {
// Early return in case of errors.
// Note that some projects/customers do not permit early return (you need
// to check code style rules for your project).
// Code usually more readable when you early return on error instead of
// writing nested if, but for historical reason or to be compliant with
// old (like more than 20 years old) compilers this is not always possible.
//
return ERROR_INVALID_ARGUMENT;
}
// Output parameters are usually non-const pointers to a type.
// In this case we have a pointer to int, so we can "write" to the variable
// pointed by c.
*c = a / b;
return ERROR_SUCCESS;
}
int main(int argc, const char* argv[]) {
int x = 14;
int y = 7;
// We can only have a result if we first declare a variable where to write it
// So here we declare `int z` and pass the pointer to it as a the output argument.
int z = 99999;
Error err = divide_3(x, y, &z);
// Now err is equal to ERROR_SUCCESS and z is equal to 2
// In C language, enum are just numbers and when you
// print them, you see just the integer value
printf("err=%i, z=%i\n", (int)err, z);
// output is:
// err=0, z=2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment