標籤:

為什麼 C/C++ 的宏一直沒怎麼發展?

比如一直不支持循環,一直不支持調用外部程序進行展開,甚至一直不支持塊定義,多行的宏要加一大堆 等等。

搞得 Kernel 源碼里用好多輔助程序來做本來應該是宏做的事情。

也不是沒有榜樣,Lisp 的宏可以用 Lisp 中的所有功能,很多時候真的非常方便。


C++中的預定義宏和條件編譯宏只是簡單的在編譯期前進行預編譯文本替換,整體的能力如同m4。某種程度上可以作為生成代碼的工具,但局限性太大。特別是call-by-name這一點。。針對這一點, @vczh曾設計過FPMacro來避免和增強,參見如何設計一門語言(十)——正則表達式與領域特定語言(DSL)中相關內容。

至於為什麼本身沒有發展,很大的一點是考慮兼容性的問題。

不過同樣與Lisp的強大的宏有一個相對的東西,在C++中也是非常重要的組成部分的,就是C++中的模板 (C++):編譯時進行展開生成可用代碼。同時,對於類型推斷和一些簡單的值運算也能做到在編譯期完成,通過這些精妙的設計帶來的效果不比Lisp的宏系統少。(當然在美觀性和友好性方面就不要多說了,C++程序員的內傷。

如同 @白如冰一樣,推薦你去了解一下boost,特別是boost::mpl。

另推薦參考:

Template metaprogramming

C++Templates中文版 (豆瓣)

C++模板元編程 (豆瓣)

C++設計新思維 (豆瓣)

另貼一個很明顯的利用模版做出來的東西,by @vczh

https://gist.github.com/kenpusney/9274727


C++連reinterpret_cast這種事情都幹得出來,所以說他之所以保留宏這麼用起來很煩躁的語法,首先一個是你無法完全避免他,第二個就是,他想讓你在可以用別的東西的時候不要用宏,通過【宏用起來很噁心】來做到這一點。


C/C++中的宏本來就是文本替換,至於你想替換出什麼效果,完全取決於你用什麼去替換

你可以看看boost的源碼,宏一樣可以用的很複雜


因為相對lisp而言c的語法過於複雜而缺乏規律,所以構造通用meta language就困難的多。這方面的研究也非常缺乏,主要都去搞語言本身,需要什麼就往裡面塞,這個難度要小的多。

但也不是不會發展,有少數人還在尋求更好的方案,標準委下面也有小圈子討論這個,雖然尚未看到希望。我覺得這和語言本身定義是密不可分的,lisp走了一個投機取巧的路,但畢竟也不方便。

Boost.preprocessor其實已經做的不錯了,對寫庫和重用代碼有很大幫助。


這是歷史遺留吧, 要想讓你爽C++就是別的東西了.


你都寫到那麼複雜的一個調用了,為什麼不直接寫成函數?


推薦閱讀:

malloc是從系統堆裡面動態申請空間,那與char *申請的空間有什麼區別?
不用虛析構函數也不會造成內存泄漏的原因是什麼?
C/C++靜態庫中的函數在這個靜態庫被使用時還有被inline的可能嗎?
為什麼現在有很多人甚至大學授課還在堅持VC6?

TAG:CC | 宏計算機 |