本文將於日後整理於 侯捷網站/答客問 /C++ Primer 中文版
侯捷網站:www.jjhou.com
----------------------------------------------------------------
●C++ Standard 相容編譯器
我想很多人關心,目前市面上哪些廠牌的 C++ 編譯器,完全支援 C++ Standard。C/C++ User Journal, Nov. 1999 的【C/C++ Stanadrd FAQ】專欄中,P.J. Plauger 對此問題的回答是:目前還沒有完全支援 C++ Standard 的編譯器產品。P.J. Plauger 閱歷廣泛,他的文章提到不同平台上的多種C++ 編譯器(但並沒有深入談論,都只淺淺帶過)。
回憶歷史,C Standard 定案後,市面上立刻出現一大堆宣稱與標準規格完全相容 的 C 編譯器。為什麼符合 C++ 標準規格的編譯器卻是如此難產呢?我想因素之一是,C++ 遠比 C 複雜得多,後期導入的一些性質(如 member templates, template partial specialization...)在編譯器技術層面上更是高難度。因素之二是,C++ Standard library 是個浩大的工程,而編譯器通常是以 bundle 的方式搭配其他公司的 C++ Standard Library,所以彼此的進度、技術、相容性都需要更多時間來協調配合。因素之三是,C++ 編譯器的價值比較,已經不再只是單純地比誰對 C++ Standard 的支援程度高(或甚至也不是比較誰的編譯速度快),而是比較在特定平台上對客戶是否有更多的企業服務。拿 Windows 環境上的 C++ 編譯器來說,「誰提供更好的 Windows 應用軟體開發工具與開發資源」可能比「誰更貼近 C++ Standard」,對客戶而言更為重要。
但是大家還是會很關心哪家編譯器最貼近 C++ Standard -- 即使這不影響你對 C++ 編譯器的選擇。
●個人經驗
自從我將 L&L(Lippman & Lajoie)的《C++ Primer》譯出後,面對 C++ Standard 所規範的許多嶄新性質,就有一股躍躍欲試的衝動。其後由於個人興趣,也因為課程需要,把《C++ Primer 中文版》整個重新檢閱一遍,並動手在三種不同的編譯器上進行測試(都是 PC/Windows 平台)。以下整理我的個人經驗,供各位參考。
我儘量為每一個主題列出一份簡短而完整的測試碼。這些或許不是太嚴謹的測試,但是如果這些符合 C++ Standard 的程式碼無法通過編譯,我們說這個編譯器未能奉行 C++ Standard,並不過份。但反過來說,通過我所列之簡易測試者,或許仍有可能在更複雜的情況中出錯(尤其是template 相關主題)。如果您有相關經驗,歡迎提供出來造福大家。
沒有什麼好點子,可以對以下各個主題編號排序。所以我以它們出現在《C++ Primer 中文版》上的頁次為序。擁有英文版的讀者請注意,中文版和英文版頁次完全相同。
●測試環境
我的測試環境是:Intel Pentium,Windows 98,三套 C++ 編譯器:
(1) Microsoft Visual C++ 6.0(以下以 VC6 代表)
(2) Inprise Borland C++Builder 4.0 (以下以 BCB4 代表)
(3) GNU C++ egcs-2.91.57(以下以 G++ 代表)
請注意,GNU C++ 有著各種作業平台上的各種版本。我只用手上的egcs-2.91.57(for win32) 來測試。
我在 Windows 98 文字模式(console mode)底下進行編譯。以下是三種編譯器的環境設定(其中路徑可能與你不同。如欲循此方式設定,請自行修改):
★VC6 環境設定
@echo off
rem
set PATH=C:\MSDEV\VC98\BIN;C:\MSDEV\COMMON\MSDEV98\BIN
set INCLUDE=C:\MSDEV\VC98\INCLUDE
set LIB=C:\MSDEV\VC98\LIB
★BCB4 環境設定
@echo off
rem
set PATH=C:\inprise\CBuilder4\BIN
set INCLUDE=C:\inprise\CBuilder4\INCLUDE
set LIB=C:\inprise\CBuilder4\LIB
★G++ egcs-2.91.57 環境設定
@echo off
rem
set PATH=c:\CYGNUS\CYGWIN~1\H-I586~1\BIN
set INCLUDE=
set LIB=
cls
注意:C/C++ User Journal, Oct.1999, p.94 曾提過在 VC 上的一個簡易
閃避辦法,這並且也是明載於 MSDN News(Vol7, Num6, Dr. GUI column)
上的作法。設計一個巨集如下即可解決:
#define for if(0); else for
該文並說,在簡單情況下可以有效運作,但並未測試太過複雜的情況。
■C++ Primer p262 中
主題:STL list 建構時,直接給 list 的大小及初值(做為所有元素的相同初值)
測試結果:VC6[o] BCB4[x] G++[o]
實例:
#001 #include <list>
#002 ...
#003 const int list_size = 64;
#004 list<int> ilist1(list_size); // BCB4 error. VC6 ok. G++ ok
#005 list<string> ilist2(list_size); // BCB4 ok. VC6 ok. G++ ok
#006 list<int> ilist3(list_size, -1); // BCB4 ok. VC6 ok. G++ ok
#007 list<int> ilist4(list_size, 0); // BCB4 error VC6 ok. G++ ok
#008 list<int> ilist5(list_size, 1); // BCB4 error VC6 ok. G++ ok
#009 list<int> ilist6(list_size, -6); // BCB4 ok. VC6 ok. G++ ok