我正在使用具有许多不同错误代码的第三方库。包含文件包含一大堆行,如:
#define ABC_INVALID_BUFFER_SIZE 101
#define ABC_INVALID_COMMAND 102
等
在运行时,我正在开发各种错误代码,因为我正在开发我的应用程序。我想在运行时让应用程序打印出“error:ABC_INVALID_COMMAND”之类的消息,而不是打印“error:102”。
我希望有一个各种翻译地图,允许我使用地图[代码]将数字转换为文本。
所以我正在寻找的是一种机制,它允许我在编译时解析包含文件,并将其转换为map [102] = string(“ABC_INVALID_COMMAND”)。 我可以使用awk脚本执行此操作,但我想知道是否存在已存在的机制。当然,我不能成为第一个想要/需要这样做的人吗?我还没有发现一些明显的东西吗?
答案 0 :(得分:1)
你肯定不是第一个想要这个功能的人,我也会喜欢它。
不幸的是,您需要继续使用脚本。我会有一个运行make的脚本,然后每次运行你的脚本。
即使c预处理器废弃了#define的标签,你仍然可以访问它们:
cpp -dM foo.h
返回:
(some others)
#define A 1
#define B 2
你会发现你仍然需要使用返回值。
http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Preprocessor-Options.html#Preprocessor-Options
的更多信息答案 1 :(得分:1)
绝对!这可以使用X-Macros使用编译器的预处理器来完成。我经常使用它来将错误代码与字符串相关联。
完整说明:What is a good reference documenting patterns of use of X-Macros in C (or possibly C++)?
针对您的具体问题:
/*
* X Macro() data list
* - Add all new values here (and only here!)
* Format: Enum, Value
*/
#define X_ABC_ERROR \
X(ABC_INVALID_BUFFER_SIZE, 101) \
X(ABC_INVALID_COMMAND, 102) \
X(ABC_SOME_OTHER_ERROR, 200)
/*
* Build an array of error return values
* e.g. {101,102}
*/
static int ErrorVal[] =
{
#define X(Enum,Val) Val,
X_ABC_ERROR
#undef X
};
/*
* Build an array of error enum names
* e.g. {"ABC_INVALID_BUFFER_SIZE","ABC_INVALID_COMMAND"}
*/
static char * ErrorName[] = {
#define X(Enum,Val) #Enum,
X_ABC_ERROR
#undef X
};
/*
* Create an enumerated list of error indexes
* e.g. IDX_ABC_INVALID_BUFFER_SIZE = 0, IDX_ABC_INVALID_COMMAND = 1, ...
*/
enum {
#define X(Enum,Val) IDX_##Enum,
X_ABC_ERROR
#undef X
IDX_MAX /* Array size */
};
/*
* Sample function to show error codes/names
*/
static void showErrorInfo(void)
{
int i;
/*
* Access the values
*/
for (i=0; i<IDX_MAX; i++)
printf(" %s == %d\n", ErrorName[i], ErrorVal[i]);
}
答案 2 :(得分:0)
语言无法完成,预处理器会在编译器看到之前将字符串重新映射到它们的值。
常见的解决方案是:
1,一个脚本,用于生成常量列表以及一组匹配的#defined字符串
或者生成一个带有大switch语句的函数来返回字符串值。
2,用结构数组替换值
struct {
int value;
char *name;
} values;
并用一对常量“description”初始化它。 根据您使用#defines的方式,这可能无法实现。
我会编写一个脚本(awk / python / etc)来读取文本文件:
AVALUE 12
BVALUE 23
CVALUE 45
并吐出.h文件
#define AVALUE_S "AVALUE"
#define AVALUE 12
#define BVALUE_S "BVALUE"
#define BVALUE 23
然后在您的代码中,只要您需要人类可读的字符串,就可以使用AVALUE_S。