2007年9月10日 星期一
回应: Linux之父炮轰C++:"糟糕程序员的垃圾语言"
"Linux之父Linus Torvalds为了Linux内核开发而专门打造的版本控制软件Git已经引起了业界的广泛关注。昨天,有一位Dmitry Kakurin老兄在查看了源代码之后,发现使用的是纯C而非C++,表示不可理解,他直言:“别拿可移植性说事儿,这是屁话(BS,bullshit)。“(此外,他还批评Git蛮力地直接操作文本,既啰嗦又易错,而且很难跟上高层代码逻辑。)这个BS引起了Torvalds的强烈反应,他用“*YOU* are full of bullshit.“(你才满嘴屁话呢)作为自己反驳的开场白。接着,他先转向了对C++的罕见的火药味十足的炮轰..."从几年的实践来看,我觉得从面向对象这个角度来看,C++很好,但C++这个东西太复杂,太容易导致错误,用上几个模版后,编译时搞出一大堆不知所云的信息也是常事。俺是觉得C++写的东西很容易变得不可维护,尤其是有C++"高手"加入以后。而且印象中用C++做出来的可重用的库比较少。
大 家都说“我们在没有掌握得好的时候,不妨只用我们了解的那些特性。那些高级特性并不妨碍,你可以不用啊”,但这都是从单独一个人的角度来说的。放到一个团 队来说,你的队伍中有C++高手,有新手,还有更多的半生不熟的人,怎么办?Linus的考虑也是从这个角度出发的,就算你Dmitry Kakurin很懂C++,不会出什么问题,能写出漂亮的代码,但其他人怎么维护你的代码?
不过俺没有帖子里面各位这么确信,对很多事物都抱着一种敬畏的态度,因为我不知道是不是本人不够聪明,没有认识到C++的各个方面。
刚 才我统计了一下sourceforge.net上用C++和C的项目数,以及各自的处于stable和mature阶段的项目数。
total
stable
mature
C++
22462
4326(19.26%)
427(1.90%)
C
19623
4792(24.42%)
615(3.13%)
Java
26454
5097(19.27%)
353(1.33%)
Python
7224
1287(17.81%)
109(1.5%)
从总数上看似乎C++更适合大家写东西,但从stable和mature项目比率上看似乎C项目更容易稳定和成熟,可维护性高些。
不过也许这不能说明什么,因为sf.net上只是些开源软件,上面各位又说C++在windows上应用普遍,而windows上素来没有多少开源传统。又或者商业软件又有不同。各位自己乱炖吧。
参考:
- C++批判 (A Critique of C++) 没看见哪里有中文翻译
标签: programming
2006年10月1日 星期日
C++类继承中的几个小问题
是的,我一直是个Delphi的粉丝。虽然现在工作上用的是C++(而且是在用VC/MFC),但一直都没有认真去学习它。前两天听俺们项目组的C ++高手讲解了一些“基本知识”,我还是觉得这个语言太复杂了,陷阱也太多。以下有几个例子(鄙人C++确很粗浅,如有不对的地方,敬请指正)。
[@more@]第一个例子:
class Base
{
public:
virtual void MethodFoo(std::string s);
}
class Child: public Base
{
public:
virtual void MethodFoo(std::string s);
}
Base *b = new Child;
std::string s("something");
b.MethodFoo(str);
我 们会利用多态性来调用不同的MethodFoo实现,但突然有一天你觉得MethodFoo中间s是不应该发生变化的,于是加了一个const。问题来 了,很多编译器不会告诉你任何告警,但b.MethodFoo再也调用不到派生类的MethodFoo了,除非你把它们一个个都改过来。
第二个例子:
class Base
{
public:
virtual void MethodFoo(std::string s);
}
class Child: public Base
{
public:
virtual void MethodFoo(std::string s);
{
DoSometingMyself();
Base::MethodFoo(s);
}
}
突然有一天,你觉得这个设计不太合理,需要在Base和Child之间再插入一层(class Middle),这就意味着你得修改Child所有函数中类似上面黑体的部分,把它们改成Middle::MethodFoo什么的。
第三个例子:
我 们知道C++中支持多继承,但它对于多个基类中有同名同类型函数的问题没有提供解决方法(也许你会说,我们不应该写这样的代码,但仔细想想X, Y都是接口(C++用纯虚类来做)的情况下,难免会有重名的)。对于X, Y均派生自B,而C又牌证自X+Y这种”恐怖的菱形,它有一个"workaround"是用虚基类,但这要求更改X, Y的代码,使得它们虚拟继承自B。
-----------
是的,这三个问题在Delphi中均可以避免:
1. 要重新实现虚方法必须用override关键字;而带有override声明的方法如果参数不一致,编译器会报错;如果基类中不存在叫这个名字的方法,也会报错。而你确实要用同样的函数名做别的事情,得用reintroduce或者overload关键字。
2. Child::MethodFoo中调用其父类的MethodFoo时不用写Base::MethodFoo,直接写inherited MethodFoo就行了。
3. 采用方法分辨子句即可:
TChild = class(TParent, Interface1, Interface2)
procedure Interface1.MethodFoo = MethodFoo1;
procedure Interface2.MethodFoo = MethodFoo2;
procedure MethodFoo1(s: String);
procedure MethodFoo2(s: String);
end;
标签: delphi, programming, tech.misc
2006年8月6日 星期日
Inno setup, 不错
俺现在用Delphi的时候少了,业余也不怎么玩它了,有时候有点手痒。
俺在公司赖以混饭吃的那个产品原来是用 InstallShield做安装程序的,一直用的是个老版本6.22,都好几年了,有很多功能做起来相当麻烦,很多新特性也不支持;加上IS公司又查的 紧,搞得想升级到新版本又被公司卡得紧;俺又不喜欢它一个工程要一大堆目录的风格(而且还不能随便挪目录)。于是就琢磨着换个免费的工具。
在NSIS和Inno Setup之间比较了半天之后,选择了Inno Setup,最开始的原因很简单: Inno是用Delphi写的,而且居然支持用Pascal写安装脚本(好像用的是RemObjects Pascal Script引擎)。
用 了一阵下来,感觉不错:
- 用InstallShield没法自行调用函数注册COM组件(只好调用外部regsvr32:-(),这个问题在InnoSetup根本就不存在;
- 用TStrings类可 以很容易地操作非ini类的文本文件,这样原来很多配置文件里面的选项都可以用安装程序来调整了;
- 同样可以用CreateOLEObject来创建COM对象,并直接调用,俺们的XML配置文件就可以很好解决了;
- 整个工程设置都在一个文件里面,用版本配置工具管理起来 也方便
- ......
最重要的是,用Pascal写起代码来让我感觉得心应手,干嘛还要另外学习一个语法古怪的语言:-).
标签: delphi, programming, tech.misc
2006年6月11日 星期日
C/C++的字符串处理效率...咳咳
- Shlemiel得到一??在路上?T油漆的工作,他要漆在路中殓的殓?喾指艟?。第一天他拿了一罐油漆去漆好了300瘁的路。「做得真好!」他的老??真「你手倪真快啊!」然後就斤他一??泾板。
- 第二天Shlemiel只漆了150瘁。「呃?影。??]有昨天好,不咿也??是很快。150瘁也很了不起。」也斤他一??泾板。
- 第三天Shlemiel只漆了30瘁。「只有30瘁而已!」老??就哇哇大叫了。「呃??在是?o法接受!第一天你漆了十倍的樘度耶!究竟怎?N回事啊?」
- 「我也?]揠法啊,」Shlemiel真「我每隔一天就滕油漆罐愈?碛?哞啊!」
这人很傻是吧?但C/C++里面字符串处理函数strlen, strcat是怎样实现的呢?
Joel说(英文原文),这就是为什么一些系统一个目录下有上千个文件时就效率急剧下降的原因,也是为什么Excel后来采用了Pascal的字符串处理方式效率就提高了很多的原因。
标签: programming, tech.misc
2006年1月31日 星期二
GUI程序的RAD和脚本化?
但UI怎么办呢? 当然是要求有一些常用控件的,而且有事件响应能力,脚本中也要求能够操纵这些UI元素。基于俺个人多年的爱好,最好是能够同时编辑UI和事件处理代码(我认为没有这个功能就不能叫RAD:-)。
比较理想的是像Excel/Word那样用VBA(该项目是在Windows上用MFC开发的),但似乎这方面的例子和文档都比较少,也拿不到VBA的试用版来评估一下。
从目前看到的一些东西来看,Windows下比较接近我们的需求的是Script Builder, 它是基于Delphi的,可以直接使用ActiveX或者Delphi编写的package,支持ActiveScript(也就是说可以使用 VBScript, JScript, Python和Perl了)和DelphiScript。如果我们自己的项目是用Delphi开发的,把这个集成进去应该是件很酷的事情。(这个东西实际 是基于以前见过的Dream Scripter,只是UI表现上做得更加接近了我们“用脚本写程序”的想法而已。)
再看一些其他的GUI toolkit吧:
- gtk有一个glade来编辑界面,然后我们可以在pygtk/python-glade或者gtk-perl/glade-perl来写响应代码,没法直接编辑界面代码(毕竟glade不是针对具体哪种语言的) P.S 刚刚在Planet Debian TW上看见yungyuc介绍一个新东东Gazpacho,说是"看起來是 Python+GTK 的 IDE",我还高兴了一阵,拉下来试试却发现只是一个改为完全用python写的一个glade而已。当然,我们可以以此为基础再来扩展。
- wxWidgets有个wxGlade, 是模仿Glade的,不用多说。
- Qt有Qt-Designer来编辑UI, 但这个东西也是跟glade差不多;同时它还有个Qt Script for Application,使得可以通过Qt Script(基于JavaScript)来操纵UI,不知道这两个东西是否可以接合,不过这已经很不错了。
- SpecTcl是一个tk的界面设计器,不过它可以直接生成脚本(tcl甚至perl, python, ruby)
- Java方面我用过JBuilder, 对于Borland的这种方式,用最近最红火的郭德纲的话说:“ 这个杭子,我做兴!”,简直" 要了亲命了"。只是因为java的烦琐,一个用JBuilder编写的略微复杂的界面,其创建UI部分的代码,基本上是不可手工维护的。至于Eclipse上UI设计器,还没玩过,不瞎说了。
说了这么些,有朋友会问,到底你们用的哪种?呵呵,记住我们的程序是用MFC写的,也没有买Qt这样的界面套件。最后我们用了用友华表的 Cell控件做模板来模拟UI,上面也可以放些按钮、下拉框什么的,虽然显得很不专业,但总算能对付过去。
想 想也知道为什么这种东西没有基于MFC的: 要在脚本中操纵UI控件(当然是说比较自然的方式,比如MainForm.Statubar1.SimpleText = "hello, world", 不是我见一些高手在tcl里面用c代码封装SendMessage来操纵的那种),这显然要求界面库有良好的RTTI,以便宿主程序能够很方便地将界面控 件对象加到脚本解释器当中去,否则脚本中怎么操纵它们。MFC有这些个嘛? ──除非完全自己手工来折腾。
补充:
1. 忘了gambas了,这个接近于Visual Basic,UI是用Qt写的。
2. mozilla的XUL应该是一个很不错的选择,而且传言很快将加入python支持,只是比较耗内存(似乎也没界面编辑器)。
标签: delphi, programming, python, script, ui
2005年7月18日 星期一
高版本pkg-config的问题
Briefly, on my cygwin, `pkg-config --libs gtk+-2.0' would output:
0.17: -Wl,--export-dynamic -lgtk-x11-2.0
0.15: -Wl,--export-dynamic -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangoxft-1.0 -lpangox-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lintl -liconv
I think the latter is right. Perhaps cygwin port forgot to specify '--enable-indirect-deps' option while building.
这 几日在公司做设计,需要划UML图,于是就想用dia,装了个windows版本,谁知道老崩溃,于是想念起cygwin版本来。原来在cygnome2 已经做过移植,但跟现在cygwin自己的gtk2用了不同的prefix,就重新编译一下吧。 因为在公司空闲时间不多,于是就在家里先搞好了build script和cygwin patch打算然后重新在公司直接编译一遍。
谁 知道在家里弄好的patch到了公司就不用了,configure的时候报告gtk+-2.0不存在,检查config.log,发现是测试gtk+- 2.0时没有g_xxx等函数的定义,也就是说缺少-lglib-2.0。手工添加了一把,到了生成lib/libdia.la时还是出错,这回说是没有 gdk_xxx的定义。
觉得有问题,回头再查看config.log, 看到pkgconfig --libs gtk+-2.0的时候就只输出了-Wl,--export-dynamic -lgtk-x11-2.0. 怎么回事?gtk+-2.0依赖于gdk,glib等,它应该自动将它们的libs也提取出来啊,总不能让我在应用程序中自己来调用吧(比如我怎么知道该 添加gdk-x11还是gdk-win32,我怎么知道它有没有使用libintl?)
回到家一试验,果然家里的pkgconfig输出的 是正确的(有-lpango-1.0 -lglib-2.0.....)。但pkgconfig是个小程序,好像没有什么配置上的不同导致这个问题啊?难道是版本问题?一检查,家里用的还是 0.15版本,而公司里用的是较新的0.17。奇怪,老版本居然没问题,而新版本有。
标签: linux, programming
2005年4月14日 星期四
终极编程语言: C-omega (玩笑)
Cω自去年7月份就要微软研究院的网页上公布出来,但C#的光芒完全把这门语言掩盖住了,近期在微软的官方站点上又刊登了一些有关Cω的文章,不知它是否会如当年C#的出现一样再次吸引住开发者的眼球,再次带来生产力的突破?
......
DarkSchneider:
其实,微软的“下一代”语言真正的含义是:“C oh my god!“ (2005.04.13)
标签: programming
订阅 帖子 [Atom]