作者FRAXIS (喔喔)
看板C_and_CPP
標題[心得] X-Macros
時間Mon Jun 29 22:36:41 2009
以前在網路上亂逛的時候看到的技巧,跟大家分享。
假設有一個enum,其中包含三個item:first, second, third。
enum order { first, second, third };
然後我希望可以建立一個字串陣列,可以跟這個enum一對一對應
const char *array[] = { "first", "second", "third" };
但是這邊有一個麻煩是,如果哪一天改了order,卻忘記改array
的內容,程式就會出錯。同時間維護兩邊的一致性很麻煩,所以才
產生了X-Macros的技巧。
當然,解決一致性的問題不只這種方法,這方法多少也降低了程式
的可讀性,還會增加除錯的困難。
下面是一個很簡單的範例
先寫一個data.def的檔案,內容如下
X(0, first)
X(1, second)
X(2, third)
然後在宣告enum的地方改成
#define X(a,b) b=a,
enum order {
#include "data.def"
};
#undef X
這邊會自動把order展開成
enum order {
first=0,
second=1,
third=2,
};
然後在array宣告的地方改成
#define X(a, b) [a]=#a,
const char *array[] = {
#include "data.def"
};
#undef X
這邊會自動把array展開成
const char *array[] = {
[first]="first",
[second]="second",
[third]="third",
};
所以array[first] = "first", array[second] = "second",
array[third] = "third"
這邊有用到C99的語法,用ANSI C的話要稍微修改一下。
如果此時要新增一項fourth,只要改變data.def即可。
以這個技巧延伸,可以把X的定義修改,讓它除了可以產生資料的
宣告之外,還可以產生程式碼,只是用巨集做越多事情,程式會越
難維護就是了。
如果要看更進階的用法,請參考下列網站
http://en.wikipedia.org/wiki/C_preprocessor#X-Macros
http://www.ddj.com/cpp/184401387
http://op.closedformodification.com/2006/06/18/x-macros/
http://liw.iki.fi/liw/texts/cpp-trick.html
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.119.162.51
推 bobhsiao:推分享啊~你挖出好多有趣的東西 06/29 23:00
推 james732:很奇妙,推!! 06/30 04:42