Разработка общедоступных кодов ошибок на C для библиотеки

#c #api-design #library-design

#c #api-дизайн #библиотека-дизайн

Вопрос:

Проблема дизайна, которую я пытаюсь решить, заключается в том, какой гибкий способ предоставить клиенту возможность обрабатывать ошибки, которые могут возникать при вызове библиотечных функций. Я вижу 2 подхода:

I. Поместить все ошибки, которые могут быть вызваны любыми библиотечными функциями, в общедоступный отдельный файл заголовка, например lib_errors.h :

 #define APP_ERR_OBJECT_TOO_SMALL 1 /* The object is too small */

#define APP_ERR_HOST_UNREACHABLE 2 /* Host is not reachable */

#define APP_ERR_UNKNOWN          3 /* Unknown error */
  

И включите его во все общедоступные заголовочные файлы библиотеки.

header1.h :

 #include "lib_errors.h"

/**
 * -1 - on error 
 *      error_code is set to APP_ERR_OBJECT_TOO_SMALL the buf is too small
 *      error_code is set to APP_ERR_UNKNOWN in case of unknown error
 */ 
int hdr1_drain(void *buf, size_t sz, int *error_code);
  

header2.h :

 #include "lib_errors.h"

/**
 * -1 - on error 
 *      error_code is set to APP_ERR_HOST_UNREACHABLE if the host is unreachable
 *      error_code is set to APP_ERR_UNKNOWN in case of unknown error
 */ 
int hdr2_connect(char *add, int *error_code);
  

Проблема, которую я вижу: все ошибки, которые может вызвать библиотека, будут включены в каждый из файлов заголовков, даже те, которые сам заголовок не вызывает.

II. Для определения ошибок, специфичных для заголовка, в каждом файле заголовка:

header1.h :

 #define HDR1_OBJECT_TOO_SMALL 1
#define HDR1_UNKNOWN          2
  

header2.h

 #define HDR2_HOST_UNREACHABLE 1
#define HDR2_UNKNOWN          2
  

Проблема, которую я вижу: количество дублирующегося кода увеличивается с увеличением количества распространенных ошибок. Все распространенные ошибки должны дублироваться в каждом общедоступном заголовочном файле.

Итак, я в настоящее время не понимаю, какой из них выбрать. Вероятно, есть другой способ подойти к проблеме проектирования. Первый подход, похоже, ближе к POSIX errno .

Комментарии:

1. errno это не битовая маска, это просто последовательные значения: 1, 2, 3, 4, ...

2. @Barmar Ни мои коды ошибок. 1, 2, 4, etc. . Я выбрал степени 2. Считается ли это неправильным?

3. Степени 2 являются битовыми масками. Это позволяет вам комбинировать их следующим образом APP_ERR_OBJECT_TOO_SMALL | APP_ERR_UNKNOWN , чтобы указать, что произошло несколько ошибок.

4. Ваш метод означает, что может быть только 32 разных кода ошибок.

5. Я не вижу ничего плохого в первом подходе. Вы могли бы просто поместить весь интерфейс вашей библиотеки в один заголовок.

Ответ №1:

Вы можете объединить два подхода. Поместите все распространенные ошибки в один заголовок, а затем ошибки, относящиеся к конкретному приложению, в заголовок приложения.

lib_errors.h:

 #define ERR_UNKNOWN 1
...
#define LIBERR_LAST 100
  

заголовок 1.h:

 #include "lib_errors.h"

#define HDR1_OBJECT_TOO_SMALL (LIBERR_LAST   1)
...
  

заголовок 2.h:

 #include "lib_errors.h"

#define HDR2_HOST_UNREACHABLE (LIBERR_LAST   1)
...