I am writing a library for some data structures in C that will be used in embedded systems. I have had issues designing and coming up with a solid error handling plan. This API is only subject to logic errors which is why I am so conflicted. By this I mean the preconditions might be: "x != NULL" or "index < size of container".
Doing a lot of research on the forums here, it seems as though their are several approaches for error handling in C:
- Use errno. I believe the general sentiment is errno should be avoided at all costs, and its design philosophy is outdated, so this is a no-go.
- Use error codes. Every function could either return error codes, or the user could pass a pointer for the error codes to be assigned. I believe returning error codes is much more elegant than the latter, but some functions will feel clunky because the user will have to pass a pointer to get the "output" of the function. One of the functions is "get_index_of_object". You can see how this would be anything but convenient.
- Use asserts that will be disabled in production build. This is what I am leaning towards as of now, since these data structures will be used so often, the performance boost of having the asserts disabled in production build might be noticeable (although I have no data to support this as of now). As previously mentioned, this API can only be affected by logic errors (users not respecting the preconditions of the functions). To my understanding, asserting logic errors for debugging purposes is encouraged, but is it good practice to use asserts for validating function arguments in a public API? Especially when it will be used in embedded systems?
- Check the preconditions, and return early if they are violated. My biggest issue with this approach is debugging might be a nightmare for someone years later. Some functions could return, say "NULL", but others such as "get_index_of_object" can't return a value that will describe error.
- Use a combination of the above four error handling methods. I would like to avoid code bloat and keep things as convenient as possible, but this is an option.
I am curious as to what yall have to say.