我正在编写一个简单的解析器来读取配置文件.config.h接口只有三个 主要功能如下,
config_init();
config_dinit();
config_parse();
config_read_value();
我的问题是这些函数会发出不同类型的错误,例如,
config_init() emit , FILE_NOT_FOUND,FILE_EOF_ERROR,FILE_OPEN_ERROR, ...
config_dinit() emit , NOT_INIT_ERROR ,
config_parse() emit , PARSE_ERROR, OVERFLOW_ERROR, INVALID_CHARACTER_FOUND_ERROR,...
config_read_value() emit, SECTION_NOT_FOUND,KEYWORD_NOT_FOUND,OVERFLOW_ERROR,NOT_INITIALIZED_ERROR,INVALID_STATE_ERROR,... etc.
Then I create enums for each function, for by using these names ,
enum Config_ParseError{...} , enum Config_InitError{...} ,enum Config_ReadValueError{..}
etc.
某些枚举值相互重叠,也会出现“编译错误”。喜欢 OVERFLOW_ERROR,
我正在打开你的建议,
我已经对google进行了快速研究,发现了最受欢迎的IRC客户端 源代码定义了这样的枚举,enum {
CMDERR_OPTION_UNKNOWN = -3, /* unknown -option */
CMDERR_OPTION_AMBIGUOUS = -2, /* ambiguous -option */
CMDERR_OPTION_ARG_MISSING = -1, /* argument missing for -option */
CMDERR_UNKNOWN, /* unknown command */
CMDERR_AMBIGUOUS, /* ambiguous command */
CMDERR_ERRNO, /* get the error from errno */
CMDERR_NOT_ENOUGH_PARAMS, /* not enough parameters given */
CMDERR_NOT_CONNECTED, /* not connected to server */
CMDERR_NOT_JOINED, /* not joined to any channels in this window */
CMDERR_CHAN_NOT_FOUND, /* channel not found */
CMDERR_CHAN_NOT_SYNCED, /* channel not fully synchronized yet */
CMDERR_ILLEGAL_PROTO, /* requires different chat protocol than the active server */
CMDERR_NOT_GOOD_IDEA, /* not good idea to do, -yes overrides this */
CMDERR_INVALID_TIME, /* invalid time specification */
CMDERR_INVALID_CHARSET, /* invalid charset specification */
CMDERR_EVAL_MAX_RECURSE, /* eval hit recursion limit */
CMDERR_PROGRAM_NOT_FOUND /* program not found */
};
它定义了没有任何名字的枚举,是不是一个好的风格?那么为什么是什么原因 那?
真的需要一些更好的命名决策。请不要伤害我,我只是 开始阅读“写美丽的C代码”一书。
先谢谢。 三墩。
答案 0 :(得分:19)
我通常是整个库的一组错误返回的粉丝。这种方式在消费者中他们不必担心“是对X的-1输入错误或无法连接到Y”。
我也是E_
前缀的粉丝,但实际上任何人都会这样做:
enum _config_error
{
E_SUCCESS = 0,
E_INVALID_INPUT = -1,
E_FILE_NOT_FOUND = -2, /* consider some way of returning the OS error too */
....
};
/* type to provide in your API */
typedef enum _config_error error_t;
/* use this to provide a perror style method to help consumers out */
struct _errordesc {
int code;
char *message;
} errordesc[] = {
{ E_SUCCESS, "No error" },
{ E_INVALID_INPUT, "Invalid input" },
{ E_FILE_NOT_FOUND, "File not found" },
....
};
答案 1 :(得分:2)
我认为这是好风格。 CMDERR_前缀将相关的错误代码组合在一起(假设它们与某种“命令调用/执行”相关)
由于您的所有示例似乎都与您的配置函数有关,因此我只使用CONFIG_前缀(或简称为CFG_)使用一个枚举定义。
enum Config_Errors {
CONFIG_FILE_NOT_FOUND,
CONFIG_FILE_EOF_ERROR,
CONFIG_FILE_OPEN_ERROR,
//etc.
};
公共前缀背后的原因是,当使用枚举类型时,您希望明确该类型的成员都属于同一组。
答案 2 :(得分:2)
IRC客户端源代码中的CMDERR_
前缀是一种很好的风格,但定义没有任何名称的枚举不是一个好的风格。不好,因为你不能说它是枚举类型,只有下面的整数类型:
CMDERR function1();
int function1(); // actually returning CMDERR unnamed enum
并且您无法使用如下所示的枚举类型定义变量:
CMDERR errResult;
int errResult; // actually errResult is CMDERR unnamed enum