早就聽(tīng)說(shuō)bcb(borland c++ builder)是一個(gè)強(qiáng)大的RAD開(kāi)發(fā)工具,也早就聽(tīng)說(shuō)曾經(jīng)的borland搞出的編譯器堪稱(chēng)經(jīng)典。
恰好最近在做一個(gè)GUI工具,想在界面開(kāi)發(fā)上盡量快一點(diǎn)。每一次用上MFC都讓我覺(jué)得渾身難受,總有些常用的
界面功能它就是沒(méi)有。在接口實(shí)現(xiàn)上,MFC基本上就只是封裝了WIN API而已。想想世界上還有什么強(qiáng)大的GUI庫(kù),
找了一下,其實(shí)不管GUI庫(kù)封裝的怎么樣,我更多地還是需要一個(gè)工具,能夠快速地堆積出界面。
于是,在網(wǎng)上下載了被國(guó)人精簡(jiǎn)了的bcb2009。然后,噩夢(mèng)開(kāi)始了。首先,我需要把邏輯層代碼(也就是實(shí)現(xiàn)具體
功能的那一層)移植到BCB下。然后得到了很多和語(yǔ)法相關(guān)的編譯錯(cuò)誤:
1.
E2397: Template argument cannot have static or local linkage
這個(gè)錯(cuò)誤發(fā)生于:
void func()
{
struct Info
{
};
std::queue<Info> abc;
}
它的意思是,模板參數(shù)必須是全局鏈接的,總之它不允許std::queue的參數(shù)是一個(gè)在函數(shù)內(nèi)部臨時(shí)定義
的類(lèi)型(誰(shuí)來(lái)告訴我這是C++標(biāo)準(zhǔn))。
2.
E2357 Reference initialized with 'FileLoader::RawData', needs lvalue of type 'FileLoader::RawData'
這個(gè)錯(cuò)誤發(fā)生于:
FileLoader::RawData FileLoader::GetRawData() const;
FileLoader::RawData &raw = loader.GetRawData(); //不能用引用
很久沒(méi)看C++書(shū),所以,誰(shuí)又來(lái)告訴我C++標(biāo)準(zhǔn)里,這里到底能不能用引用?
3.
E2515 Cannot explicitly specialize a member of a generic template class
這個(gè)錯(cuò)誤發(fā)生的情景更復(fù)雜些:
template <typename _Tp>
class Test
{
template <typename _U>
class Other;
template <>
class Other<void>
{
};
};
意思是說(shuō),我不能在一個(gè)模板類(lèi)里特化成員模板類(lèi)。誰(shuí)又來(lái)告訴我標(biāo)準(zhǔn)規(guī)定的是什么?
4.
void func( Obj &a )
{
}
func( Obj() );這個(gè)也被視為錯(cuò)誤。必須得在調(diào)用func之前自己定義個(gè)臨時(shí)變量。
5.
我曾經(jīng)留下了關(guān)于宏遞歸的一些代碼,被用在我寫(xiě)的lua-binder和lua-caller中自動(dòng)生成代碼。這下好了,
BCB開(kāi)始警告我,我的這些宏不能工作了。它和MSVC在某些事情上分歧可真是大:
#define PARAM( n ) ,typename P##n //注意這個(gè)宏包含一個(gè)逗號(hào)
#define CHR( x, y ) CHR1( x, y )
#define CHR1( x, y ) x##y
#define BCB_ERROR( a, b ) CHR( a, b )
BCB_ERROR( 1, PARAM( 1 ) ) 當(dāng)這樣使用宏時(shí),基于我在GNU C上看到的關(guān)于宏的規(guī)則,會(huì)先展開(kāi)
PARAM(1),于是得到BCB_ERROR( 1, ,typename P2 )。然后,BCB認(rèn)為PARAM(1)展開(kāi)的逗號(hào)需要參與
BCB_ERROR的展開(kāi)了。于是,我的整個(gè)宏庫(kù)無(wú)法工作了。
關(guān)于這個(gè)問(wèn)題,我直接用MSVC寫(xiě)了個(gè)生成器,讓MSVC替我生成各種參數(shù)的lua-binder和lua-caller,然后
寫(xiě)成外部頭文件,最后直接在BCB里包含了這些頭文件。從而使我的lua-binder和lua-caller可以繼續(xù)使用。
然后,我的1W多行代碼終于在BCB下50多個(gè)WARNINGS的提示下編譯成功了。懷揣著興奮的心情,想自己終
于可以rapid開(kāi)發(fā)界面了。創(chuàng)建了個(gè)VCL FORM APPLICATION,噩夢(mèng)又開(kāi)始了:
1.
BCB莫名其妙地在我編譯一個(gè)CPP文件時(shí)給出如下提示:
F1004 Internal compiler error at 0x59b4ea8 with base 0x5980000
看起來(lái)像是BCB的編譯器給崩潰了。囧。google了一下,發(fā)現(xiàn)不是我人品問(wèn)題,很多人遇到相同的問(wèn)題。
別人給出的解決方案是:restart your bcb。從昨天晚上到現(xiàn)在為止,這個(gè)錯(cuò)誤發(fā)生了好幾次。
2.
new std::ofstream();會(huì)讓程序崩潰,往不該寫(xiě)的地方寫(xiě)了東西。我就奇怪了,你BCB自己帶的C++IO實(shí)現(xiàn),
難道還有BUG?再次google,還真發(fā)現(xiàn)是BCB自己的BUG,并且在幾個(gè)版本之前就存在這個(gè)BUG。那個(gè)天真
的老外還說(shuō)希望在BCB2009下能被修復(fù)。修改方案如下:
1)xlocale文件里把這句話注釋了:*(size_t *)&table_size = 1 << CHAR_BIT;
2)xlocale里把成員_Id_cnt訪問(wèn)屬性改為public,然后在自己的文件里定義一次。
3.
程序終于可以運(yùn)行了。但是BCB的IDE環(huán)境總是不那么貼心。我移動(dòng)了幾個(gè)窗口改成我習(xí)慣的樣子,但是一重啟
居然又恢復(fù)成default(難道是因?yàn)楸I版)。它的智能提示似乎總是跟著鼠標(biāo)指針,有時(shí)候指向某個(gè)符號(hào),鼠標(biāo)
就顯示忙。為了提示某個(gè)類(lèi)的成員,某個(gè)函數(shù)的原型,BCB偶爾都會(huì)卡一下。其實(shí)我不介意我的編輯器沒(méi)有這
些提示功能,在MSVC下我也從不用VA來(lái)幫我寫(xiě)代碼。我甚至不厭其煩地在VIM下敲代碼切窗口去看函數(shù)原型,
但是,你他媽作為一個(gè)IDE就得像個(gè)IDE的樣子,要不,你干脆關(guān)掉所有功能,別給我卡就行了。
這個(gè)時(shí)候我開(kāi)始懷疑選擇BCB會(huì)不會(huì)是一個(gè)錯(cuò)誤的開(kāi)始,或者說(shuō)在使用某個(gè)東西時(shí),總會(huì)帶著使用其他同類(lèi)東西
的感覺(jué)甚至偏見(jiàn)去看待這個(gè)新事物。但是,在我想堅(jiān)持繼續(xù)使用BCB時(shí),我一compile,它又提示我:
F1004 Internal compiler error at 0x59b4ea8 with base 0x5980000