為什麼C++預處理期編譯期的支持比較薄弱?
01-14
預處理期和編譯期都可以看成是代碼生成的過程.元編程...但是宏只有展開,替換,字元串拼接,感覺能力很薄弱啊.弄個宏遞歸感覺死了好多腦細胞- -好麻煩...為什麼不能在預處理期支持for循環,foreach,簡單的字元串處理相關的函數.參考C#的http://ASP.NET裡面的那個Razor.前面加個@就可以開搞了,覺得@不好看,完全可以改$.就像PHP裡面的smarty引擎一樣.在預處理期對代碼進行擴充,但是宏的擴展能力雖然是圖靈完備,但是一點不好用好嗎!(摔
而且在編譯期,一切都是常量..為什麼不能有那種只會在編譯期使用,到了運行期自動擦除的變數.這樣在編譯期可以添加對static if和static for的支持.這樣寫起來代碼量比用模板特化控制模板實例化終止代碼量要少了.也可以令C++的模板元編程對於一般人更容易使用和上手C++也進化到C++11了,為什麼對於預處理器支持不能更強點...模板元編程更易用一些
因為預處理期的錯誤機制不好,這也是反對在預處理期加入很多功能的理由。對於預處理,其實最大的功能應該是僅限於一些特殊指令的處理(如#include),空白符的去掉,行號列號的添加等簡單功能,我認為這就足夠了,不應該讓預處理器承擔更多的功能。所以,每當我看見一些人寫出各種逆天的宏的時候,我都想說F**K。在C++的進化中,其實是弱化預處理期的行為,而非加強預處理期的行為。如C++11的nullptr的出現就是希望替代NULL,讓更多的錯誤可以暴露在編譯期(C/C++ 中 0 與 NULL 區別是什麼?用 delete 時,用 p=0,還是用 p=NULL 好?為什麼?這個問題的評論裡面有過探討)。如果以後有更多的新特性,我認為也應該是逐漸將更多預處理期的東西轉移至編譯期,這才是更好的路線。而至於模板這個東西,其實在編譯器裡面的實現是和普通的代碼不同的,它走的另外一條路線,遠非對預處理器的支持可以搞定的,一句話:它很複雜。
C# 的 #define 只能定義一個預處理符號,和 C/C++ 可以用函數形式的宏差遠了。
題主可以前往 C++ 委員會的提案論壇把自己的想法作為提案發出來:std-proposals :
Standard C++
c++社區的風向就是不贊成使用預處理階段的宏之類的至於boost::preprocess純粹是為了用cxx做代碼生成,真在生產環境我覺得還是用額外的程序來生成好維護一些
c++已經在著手這一部分的改進,很可能在下一版本加入的反射功能,也是未來發展的一個亮點。如果題主真心投入的話,不妨跟蹤一下http://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/reflection,做這方面的人很少,但拿得出手的都還是比較系統的。
我不這麼認為。實際上,功能這玩意是限制越小越靈活。
基於token的代碼生成會使人迷惑,也會使代碼混亂
C++不是像網頁模板引擎那樣,預處理後的html看一下渲染的對不對就能知道哪裡有問題的,html代碼生成出了問題,你可以用瀏覽器的f12工具看布局,看元素,但是對於預處理並且編譯成二進位的C++,代碼是沒法像網頁這樣來debug的,並且html解析容錯很高,不像C++這樣複雜情況少個分號一不小心都會搞掛編譯器。
如果你看過編譯器預處理後的C++代碼,會發現基本沒有可讀性,首先是大量的預處理條件指令造成的空行,其次是C++是是一門不需要靠換行和空格來區分語句的語言,很可能因為預處理的緣故,一個函數的兩個參數就離得八丈遠,更糟糕的是,預處理過程是沒法單步運行的,你也很難看出來哪部分是由哪個預處理指令生成的。C++本身擁有非常豐富的抽象能力,圖靈完全的模板本身就提供了無盡的可能性,並且不重複自己也是一個很重要的品質,你想用預處理循環來生成代碼,首先想想代碼邏輯可不可以修改呢。也許那樣的話…程序變成哈士奇以後會找不到原因?
如果像題主說的這樣做了,那麼OI比賽選C/C++語言的選手就可以用編譯時間進行計算了 ,然後測評中心就要把編譯時間一起算進去了??
推薦閱讀:
※想用用flex和bison寫個C的編譯器,應該如何處理C的宏?
※peg, ometa 解決什麼問題,ometa-js怎麼入門/正確理解和認知?
※(發散性問題,請隨意加上假設)一門編程語言同時擁有解釋器和編譯器的必要性有多大?
※如何快速而準確地判斷一門語言的語法(或部分語法)屬於哪個Chomsky Hierarchy?
※實現一個markdown解析器需要具備那些知識?