Не знаю, как вы регистрируете ошибки, но как насчет:
typedef enum
{
E_SUCCESS = 0,
E_FAIL,
...
} error_t;
typedef struct
{
error_t code;
char * error_name;
} backtrace_entry_t;
backtrace_entry_t backtrace[..];
#define FUNC_EXIT(error_code__) \
do { \
backtrace[func_id].code = (error_code__); \
backtrace[func_id].error_name = #error_code__; \
} while (0)
Затем, когда вы вызовете FUNC_EXIT(E_SUCCESS);
, вы получите обратный след для функции: {.code = 0, .error_name = "E_SUCCESS"}
Проблема в том, что вы не можете получить правильное имя, если позвоните FUNC_EXIT(var);
, где var
- это некоторая локальная переменная.
Другой вариант, хотя и не является автоматическимone:
typedef enum
{
E_SUCCESS = 0,
E_FAIL,
...
NOF_ERROR_CODES
} error_t;
#define MAP_E_CODE_TO_NAME(error_code__) [error_code__] = #error_code__
const char * error_to_name_mapping[NOF_ERROR_CODES] = {
MAP_E_CODE_TO_NAME(E_SUCCESS),
MAP_E_CODE_TO_NAME(E_FAIL),
...
};
Даст массив const char *
с {"E_SUCCESS", "E_FAIL", ...}
, который вы можете использовать следующим образом:
printf("The name of error code %d is '%s'", error, error_to_name_mapping[error]);
Проблема в том, что вы должны иметь положительное значениек ошибкам с увеличением значений.