【发布时间】:2019-07-12 18:32:18
【问题描述】:
我有一个非常人为的错误代码系统(数百个非顺序值,C 语言),同样人为地转换为人类可读的错误消息。
我正在考虑重构它,但我不确定将值映射到其对应字符串的最佳方式。有小费吗?
错误代码是唯一的,不能用来组成新代码。
错误代码的构建使得每个代码都有一个 base 值,指定它属于哪个模块。警告和状态消息有偏移量:
#define SOME_MODULE_ERR_BASE 0x120000
#define OTHER_MODULE_ERR_BASE 0x130000
#define STATUS_OFFSET 1000
#define WARNING_OFFSET 2000
/* Error codes as defined as needed, sequentially from the base value */
#define SOME_MODULE_ERR_NOT_FOUND (SOME_MODULE_ERR_BASE + 1)
#define SOME_MODULE_ERR_BAD_CRC (SOME_MODULE_ERR_BASE + 2)
#define SOME_MODULE_STATUS_BUSY (SOME_MODULE_ERR_BASE + STATUS_OFFSET + 1)
#define SOME_MODULE_WARNING_INCOMPLETE (SOME_MODULE_ERR_BASE + WARNING_OFFSET + 1)
#define OTHER_MODULE_ERR_BAD_CRC (OTHER_MODULE_ERR_BASE + 1)
#define OTHER_MODULE_ERR_NOT_FOUND (OTHER_MODULE_ERR_BASE + 2)
/*...*/
我们目前有代码来打印相应的错误字符串,但是转换(从错误代码到字符串)的过程非常奇怪,甚至添加新的错误代码也是一件苦差事。我想改进我们的日志系统,但是这个愚蠢的代码妨碍了我。通过重构错误消息打印,我将能够重构日志系统。
基本上,我想要这个:
result = SomeModuleFunc();
printf("SomeModuleFunc returned %s\n", ErrToString(result));
它会酌情打印SOME_MODULE_ERR_NOT_FOUND、SOME_MODULE_ERR_BAD_CRC、SOME_MODULE_STATUS_BUSY等。
在我看来,最简单的方法就是构建一个巨大的 switch-case 语句指向适当的字符串,但也许只是因为我想不出一个好的数据结构来简化映射过程。
【问题讨论】:
-
键值对的二叉搜索树就可以了。
-
错误报告性能重要吗?我认为一些 switch-case 实现会为你构建一个跳转表,并通过循环而不是内联测试来缩短代码。
-
错误码只是整数?喜欢
enum errors_e { ERROR_1 = 123, ERROR_2 = 43, ERROR_3 = 103958, }?有序列吗?喜欢enum { ERROR_X_1 = 1, ERROR_X_2, ERROR_X_3, ERROR_Y_1 =100, ERROR_Y_2 , ERROR_Y_3 }吗?错误代码可以由多个错误组成吗?喜欢return ERROR_X_3 | ERROR_Y_1? -
@EugeneSh. 命题的变体:您可以对包含成对错误代码和相应字符串值的数组进行二进制搜索。
-
仅仅因为错误值是非顺序的,并不意味着您不能使用具有直接代码到索引对应关系的简单表。如果某些条目没有消息也没关系。这里的主要潜在问题是,如果错误编号之间存在 大 间隔,那么表格会浪费大量空间。
标签: c algorithm data-structures error-handling