宏擴展&代碼生成有優點&缺點。你最喜歡的方法是什麼?爲什麼?我們應該什麼時候選擇一個呢?請提供建議。謝謝!C/C++宏擴展與代碼生成
宏擴展可以非常方便&有所幫助: http://dtemplatelib.sourceforge.net/table.htm
VS
雖然代碼生成爲您提供了大量的漂亮的代碼: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/
宏擴展&代碼生成有優點&缺點。你最喜歡的方法是什麼?爲什麼?我們應該什麼時候選擇一個呢?請提供建議。謝謝!C/C++宏擴展與代碼生成
宏擴展可以非常方便&有所幫助: http://dtemplatelib.sourceforge.net/table.htm
VS
雖然代碼生成爲您提供了大量的漂亮的代碼: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/
這是一個權衡額外的好處。讓我舉個例子。我在1985年左右偶然發現了differential execution的技術,我認爲這是編程用戶界面的一個非常好的工具。基本上,它需要像這樣簡單的結構化程序:
void Foo(..args..){
x = y;
if (..some test..){
Bar(arg1, ...)
}
while(..another test..){
...
}
...
}
和廢石與控制結構是這樣的:
void deFoo(..args..){
if (mode & 1){x = y;}
{int svmode = mode; if (deIf(..some test..)){
deBar(((mode & 1) arg1 : 0), ...)
} mode = svmode;}
{int svmode = mode; while(deIf(..another test..)){
...
} mode = svmode;}
...
}
現在,一個很好的辦法做到這一點本來是寫一個解析器C或任何基礎語言,然後遍歷解析樹,生成我想要的代碼。 (當我在Lisp中完成時,那部分很簡單。)
但是誰願意爲C,C++或其他任何語言編寫解析器?
所以,相反,我只是寫宏,以便我可以寫這樣的代碼:
void deFoo(..args..){
PROTECT(x = y);
IF(..some test..)
deBar(PROTECT(arg1), ...)
END
WHILE(..another test..)
...
END
...
}
但是,我這樣做是在C#中的時候,有人在他們的智慧決定的宏都壞了,我不我不想寫一個C#解析器,所以我必須手工完成代碼生成。這是一種皇室般的痛苦,但與通常的編碼方式相比,它仍然值得。
在C或C++中,宏擴展爲臭名昭着的難以調試。另一方面,編寫代碼生成器更容易調試,因爲它本身就是一個單獨的程序。
但是,您應該知道,這僅僅是C預處理器的限制。例如,在Lisp系列語言中,宏擴展是代碼生成,它們完全一樣。要編寫一個宏,你需要編寫一個程序(在Lisp中)來將S表達式輸入轉換爲另一個S表達式,然後將其傳遞給編譯器。
感謝您的回覆,Greg。編寫一個體面的代碼生成器需要花費更多的時間,並且宏看起來像是一件快速的黑客工作。 – Viet 2009-11-27 09:48:53
++我的情緒正好。如果有一種方法可以逐步完成預處理,那將會很好。即便如此,如果代碼生成足夠簡單,我更喜歡宏。 – 2009-11-30 15:48:05
對於C++,我更喜歡模板元編程或通過宏代碼生成,但宏仍然有其用處。
您與dbtemplatelib給出的例子可以用的C++ 0x Variadic Templates覆蓋,有喜歡的類型檢查等
感謝您的建議。模板也有其優點。可變參數宏在那裏,但可變參數模板尚未流行,因爲C++ 0x仍然是新的。 – Viet 2009-11-27 09:55:58
嗯,確切地說,它還沒有出來,它將會是一個「C++ 1x」。但可變參數模板在某些編譯器中實現,例如,要使用它們與gcc,必須添加「-std = C++ 0x」作爲編譯器開關。 – hirschhornsalz 2009-11-27 14:19:19
+1謝謝邁克。這是最好的答案:) – Viet 2009-12-01 07:31:24