早就听说bcb(borland c++ builder)是一个强大的RAD开发工具,也早就听说曾经的borland搞出的编译器堪称经典。
恰好最近在做一个GUI工具,想在界面开发上尽量快一点。每一次用上MFC都让我觉得浑身难受,总有些常用的
界面功能它就是没有。在接口实现上,MFC基本上就只是封装了WIN API而已。想想世界上还有什么强大的GUI库,
找了一下,其实不管GUI库封装的怎么样,我更多地还是需要一个工具,能够快速地堆积出界面。
于是,在网上下载了被国人精简了的bcb2009。然后,噩梦开始了。首先,我需要把逻辑层代码(也就是实现具体
功能的那一层)移植到BCB下。然后得到了很多和语法相关的编译错误:
1.
E2397: Template argument cannot have static or local linkage
这个错误发生于:
void func()
{
struct Info
{
};
std::queue<Info> abc;
}
它的意思是,模板参数必须是全局链接的,总之它不允许std::queue的参数是一个在函数内部临时定义
的类型(谁来告诉我这是C++标准)。
2.
E2357 Reference initialized with 'FileLoader::RawData', needs lvalue of type 'FileLoader::RawData'
这个错误发生于:
FileLoader::RawData FileLoader::GetRawData() const;
FileLoader::RawData &raw = loader.GetRawData(); //不能用引用
很久没看C++书,所以,谁又来告诉我C++标准里,这里到底能不能用引用?
3.
E2515 Cannot explicitly specialize a member of a generic template class
这个错误发生的情景更复杂些:
template <typename _Tp>
class Test
{
template <typename _U>
class Other;
template <>
class Other<void>
{
};
};
意思是说,我不能在一个模板类里特化成员模板类。谁又来告诉我标准规定的是什么?
4.
void func( Obj &a )
{
}
func( Obj() );这个也被视为错误。必须得在调用func之前自己定义个临时变量。
5.
我曾经留下了关于宏递归的一些代码,被用在我写的lua-binder和lua-caller中自动生成代码。这下好了,
BCB开始警告我,我的这些宏不能工作了。它和MSVC在某些事情上分歧可真是大:
#define PARAM( n ) ,typename P##n //注意这个宏包含一个逗号
#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 ) ) 当这样使用宏时,基于我在GNU C上看到的关于宏的规则,会先展开
PARAM(1),于是得到BCB_ERROR( 1, ,typename P2 )。然后,BCB认为PARAM(1)展开的逗号需要参与
BCB_ERROR的展开了。于是,我的整个宏库无法工作了。
关于这个问题,我直接用MSVC写了个生成器,让MSVC替我生成各种参数的lua-binder和lua-caller,然后
写成外部头文件,最后直接在BCB里包含了这些头文件。从而使我的lua-binder和lua-caller可以继续使用。
然后,我的1W多行代码终于在BCB下50多个WARNINGS的提示下编译成功了。怀揣着兴奋的心情,想自己终
于可以rapid开发界面了。创建了个VCL FORM APPLICATION,噩梦又开始了:
1.
BCB莫名其妙地在我编译一个CPP文件时给出如下提示:
F1004 Internal compiler error at 0x59b4ea8 with base 0x5980000
看起来像是BCB的编译器给崩溃了。囧。google了一下,发现不是我人品问题,很多人遇到相同的问题。
别人给出的解决方案是:restart your bcb。从昨天晚上到现在为止,这个错误发生了好几次。
2.
new std::ofstream();会让程序崩溃,往不该写的地方写了东西。我就奇怪了,你BCB自己带的C++IO实现,
难道还有BUG?再次google,还真发现是BCB自己的BUG,并且在几个版本之前就存在这个BUG。那个天真
的老外还说希望在BCB2009下能被修复。修改方案如下:
1)xlocale文件里把这句话注释了:*(size_t *)&table_size = 1 << CHAR_BIT;
2)xlocale里把成员_Id_cnt访问属性改为public,然后在自己的文件里定义一次。
3.
程序终于可以运行了。但是BCB的IDE环境总是不那么贴心。我移动了几个窗口改成我习惯的样子,但是一重启
居然又恢复成default(难道是因为盗版)。它的智能提示似乎总是跟着鼠标指针,有时候指向某个符号,鼠标
就显示忙。为了提示某个类的成员,某个函数的原型,BCB偶尔都会卡一下。其实我不介意我的编辑器没有这
些提示功能,在MSVC下我也从不用VA来帮我写代码。我甚至不厌其烦地在VIM下敲代码切窗口去看函数原型,
但是,你他妈作为一个IDE就得像个IDE的样子,要不,你干脆关掉所有功能,别给我卡就行了。
这个时候我开始怀疑选择BCB会不会是一个错误的开始,或者说在使用某个东西时,总会带着使用其他同类东西
的感觉甚至偏见去看待这个新事物。但是,在我想坚持继续使用BCB时,我一compile,它又提示我:
F1004 Internal compiler error at 0x59b4ea8 with base 0x5980000