3

I am working on improving the code quality and portability of my C library, specifically a ring buffer implementation, that will be used in larger applications. I have encountered a dilemma regarding error code handling, and I would like to seek advice on industry best practices.

In some of my libraries, I currently use custom error codes defined as enums in the header files, like this:

typedef enum {
    SUCCESS          = 0,
    INVALID_ARGUMENT = 1,
    OUT_OF_MEMORY    = 2,
    BUFFER_OVERFLOW  = 3,
    UNINITIALIZED    = 4,
} buffer_error_t;

On the other hand, I've noticed that other libraries strictly adhere to the error codes provided by errno.h and utilize functions like perror() or strerror() to obtain human-readable error messages.

Considering that the library is intended for use in larger applications, my goal is to maximize code readability, maintainability, and compatibility with existing practices.

What are the industry best practices or standards when it comes to error code handling in libraries? Are there any widely accepted guidelines or considerations that can help me make an informed decision between custom error codes and errno.h?

2 Answers 2

6

It depends on whether your library is designed for strictly conforming C or whether you are targeting specific systems that provide extensions to the C errno.h library.

If the former, I would create my own custom error codes, such as those in your question. The only 'Standard C' errno error codes are ERANGE, EDOM, and EILSEQ. Those do not cover much and only make sense to report mathematical or string conversion errors.

On the other hand, POSIX-compliant systems for example provide a much wider range of built-in error codes, including EINVAL and ENOMEM which are relevant to your use case. A more complete list can be found here. If targeting POSIX, I would use those instead of creating your own.

C built-in error codes are required to be positive, so perhaps the return could be a signed integer, returning 0 on success, a predefined, positive error code if an applicable one exists on failure, and otherwise a user-defined, negative custom error code.

2
  • 1
    "The only 'Standard C' errno error codes are ..." --> Since C99 (at least), there are a few cases of "stores an implementation-defined positive value in errno" (file i/o), presumably not ERANGE, EDOM, EILSEQ, but unnamed - weird. Commented Jun 9, 2023 at 15:57
  • 1
    @chux-ReinstateMonica I do believe that C standard errno codes are lacking.
    – CPlus
    Commented Apr 26 at 14:50
1

What do you think is simpler and more composable?

  1. Just reusing standard facilities

    You have to document which errors might be returned (explicit enumerating not mandatory) and you are done.

  2. Creating and using your own cut-down incompatible facilities

    You introduce a whole new API which has to be written, documented, tested, remembered, and used.
    Don't forget i18n.

    Yes, all the error-codes your code uses are together, but is the list complete?
    Even if it is, merging error-codes from different sources means manual translation which is a chore and a half.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.