[英]What is the need of defining an Enum/Struct by way of macros?
我指的是來自opensource項目tig的代碼示例。 這是一個很棒的工具!
文件:tig.c
我正在努力找到定義請求枚舉的原因如下:
enum request {
#define REQ_GROUP(help)
#define REQ_(req, help) REQ_##req
/* Offset all requests to avoid conflicts with ncurses getch values. */
REQ_UNKNOWN = KEY_MAX + 1,
REQ_OFFSET,
REQ_INFO,
/* Internal requests. */
REQ_JUMP_COMMIT,
#undef REQ_GROUP
#undef REQ_
};
甚至結構......
static const struct request_info req_info[] = {
#define REQ_GROUP(help) { 0, NULL, 0, (help) },
#define REQ_(req, help) { REQ_##req, (#req), STRING_SIZE(#req), (help) }
REQ_INFO
#undef REQ_GROUP
#undef REQ_
};
可以看出REQ_GROUP
多次#defined造成混淆..至少對我而言。 我知道可能有一個很好的理由這樣做..使用宏隱藏代碼中的枚舉/結構定義的實際原因是什么?
當在同一數據源上使用不同的處理時,這通常會下降。
例如,您可能會這樣做:
#define MY_LIST X(Elem1) X(Elem2) X(Elem3)
接着:
enum MyEnum {
# define X(e) e,
MY_LIST
Last
# undef X
};
在這種情況下,使用當前 X
定義擴展MY_LIST
。
現在,在同一個文件中,我也可以使用MY_LIST
創建一個to_string
方法
char const* to_string(MyEnum e) {
switch(e) {
# define X(e) case e: return #e;
MY_LIST
case Last: return "Last";
# undef X
}
return 0;
} // to_string
這樣,枚舉的值集只能寫一次,並且枚舉和處理它的許多方法都會自動與該集保持同步。
這是為了避免重復請求列表。 該列表只需要在一個地方維護, REQ_INFO
的定義,以及通過REQ_GROUP
和REQ_
適當定義從該列表自動生成枚舉和數據結構。
如果沒有這些宏,枚舉和數據結構將必須單獨維護,注意保持它們彼此一致,涉及更多的工作和更多的錯誤范圍。
您錯過了同一文件中的重要定義:
#define REQ_INFO \
REQ_GROUP("View switching") \
VIEW_INFO(VIEW_REQ), \
\
REQ_GROUP("View manipulation") \
REQ_(ENTER, "Enter current line and scroll"), \
REQ_(NEXT, "Move to next"), \
REQ_(PREVIOUS, "Move to previous"), \
< output omitted as it is too long >
因此,例如,您展示的結構擴展為:
static const struct request_info req_info[] = {
{ 0, NULL, 0, "View switching" },
< VIEW_INFO also expands to some long structure that was ommited here >
{ 0, NULL, 0, "View manipulation" },
{ REQ_ENTER, ENTER, STRING_SIZE("ENTER"), "Enter current line and scroll"},
{ REQ_NEXT, NEXT, STRING_SIZE("NEXT"), "Move to next"}
< and so on >
};
正如其他提到的答案,主要是為了保持多個結構/枚舉器同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.