作者littleshan (我要加入剑道社!)
看板C_and_CPP
标题Re: [问题] 为什麽作业系统都用C写? 而不用C++呢?
时间Sat Mar 7 13:38:03 2009
仅就我能回应的部份回应,毕竟我也没什麽料。
※ 引述《guest0079 (火辣辣的大姊姊)》之铭言:
: 一般认为C++效能较差是有几点现实上的考量:
: a. C++太多太杂太难掌握,让程式人员浪费太多时间在语言本身而非问题的最佳解上
这和程式的效能无关。如果你要说的是 C++ 的某个语言特性使得实作某些演算
法变得很困难,请举出具体实例,而且你还要证明用 C 实作会比较简单。
: b. C++会偷偷增加一些程式码来维持本身的OO特性,一不小心就多出了不必要的code
: c. C++会偷偷增加一些程式码来维持运算子过载特性,一不小心就多出了不必要的code
同上,请就这两点举出具体实例并证明同样的功能在 C 中并不会造成额外负担。
: d. 用C++物件导向实作的函式库,很方便使用没错,但代价就是负担太大(如Qt)
所以负担是什麽?同样的功能用 C 实作可以快多少?
: e. ...应该还有很多我不知道的
: 2.C++程式不易读
: 运算子过载真是太好用了,而且程式一看就懂,真是太好维护了,但是如果…
: Man a_man("大雄"); // 定义一个男人
: Woman a_woman("静香"); // 定义一个女人
: int money = MAX_VALUE;
: printf("干这是什麽鬼:%s", a_man + money + a_woman);
: 这种code要怎麽维护?先回头找一下Man与Woman中operator + 的定义
: 再确认与int作运算表示什麽,再查一下书看看运算的顺序的先後关系,如果operator
: 中又用到其他operator的过载,又要再去查,为了追一个问题,又引起n个问题,为
: 了确认n个问题,又出现n^2个问题…没完没了。程式很简洁没错,但是要怎麽debug?
: 难道每一行程式都要猜猜看吗?
所以改用 C 的写法是像这样罗?
printf("干这是什麽鬼:%s",
Add_Something_Woman( Add_Man_Int(a_man, money), a_woman) );
也不是不行啦,只是有天你发现 int 不够用要改成 long 的时候,麻烦就很
大了。而且你一样也是要去看 Add_xxxx 这些 function 的内容才知道他们
做了什麽事,而且这些 function 也会用到其它 function,debug 起来并不
会比较简单。
另外你自己也说了,「运算子过载真是太好用了,而且程式一看就懂」。这意
味着如果你会写出自己看不懂的 code,那你就不该用 operator overloading。
你可能会说,这是某个「自以为很厉害的人」写出的 code,你不得不用,那
可能是以下的情况:
1. 大家都看不懂,只有「自以为很厉害的人」看得懂 code。
这种情况当然是「自以为很厉害的人」该死。
2. 一半的人看得懂,另外一半看不懂。请你们在下次技术团队会议时好好
讨论要不要改做法。
3. 大家都看得懂,你看不懂。很不幸的,这种情况下是你该多念点书。
: 好的物件导向远比C好维护,不过C++决对不是好的物件导向语言(这句话一言难尽)
: 3.物件导向不适合底层程式
: 了解物件导向的人就知道,它是较贴进人类思维的程式写作方法,反之,它就不是
: 一个贴近底层机器运作原理的编程原则,机器语言、组语才是最贴近底层运作机制的
: 语言,想要用OO来描述机器的行为、自然法则、各式各样的protocol…等等诸如此类
: 的运作机制容易流於天马行空,任意妄为。如果硬要用物件导向来实作底层机制,可
: 能十个人有十二种不同的见解,没人看得懂彼此的程式,因为每个人对机制的感受都
: 不一样,物件结构的分析各有各的看法,没完没了。
: 当然,不用物件导向也是可以写C++程式,但那还不如用C来的单纯
: (但个人偏爱用完全无继承机制的物件架构来写C++,来当作是C的加强版)
就我的认知,物件导向的目的并不是要贴近人类的思维,而是为了软体易於维护
并扩充功能。所以如果对一个系统该如何设计,若是每个程式设计师都有自己的
意见,那当然是坐下来好好讨论哪一个做法比较容易维护、扩充。
当然,程式设计师意见不合是常有的事,但并不如你所想象的那样是天马行空的
争论,而是而实际地考虑各种设计在维护及扩充上的优劣。
: 4.C++的复杂度太高
: C公认的圣经只有一本,内文也才两佰多页,一本C++的入门书就一仟多页(C++ Primer)
: C++的功能及其运作细节多如牛毛,写了10年的程式也许还会看到自已不懂的语法,或是
: debug时发现某个平常不会注意的细节在作怪,这如果只是开发一般的AP还好,如果是开
: 发OS这种大型、不易物件化的程式时,事情就大条了。因为:
: a.开发人员太多,每人都用一种冷门的技巧,那要trace code就要买十本C++在身边才行
: b.总有人喜欢卖弄技巧,喜欢来个多重继承,自行定义运算子,把程式的复杂度弄得很高
: 自以为很强,等到程式成长到自已无法控制(可能久了也忘了)才双手一摊说:比尔盖兹
: 对不起,我要去Google上班了
: c.自已乖一点不要写出太复杂的程式就好了吗?不!因为C++支援太多种技巧、style,
: 所以有时候不得不乖乖配合别人的程式风格,想维持单一模组风格的一致性也很因难
: OS不是少数几个人就能写出来的程式,一定要有不少人力来大量的分工才能完成
: ,但高度的分工之後又必需维持紧密的偶合关系,是一项复杂度很高,极易失败的专案
: ,如果再用一个复杂度相对较高的C++工具来写的话,就难上加难了
团队开发本来就应该要先统一好 coding style,此外像是类别应该要有什麽行
为、提供哪些 method、哪些东西使用 template,则是在设计阶段就应该订好,
如果有某个程式设计师喜欢搞怪不合作,那换用 C 他还是可以完全不合作。
为了避免使用者滥用,程式语言不应该提供太多复杂的功能吗?那 C 应该先把
指标拿掉。 #define 也应该要拿掉,不然有人会写出下面这种东西:
#define begin {
#define end }
: 最後,我很好奇某人说:C++的sort大胜C的qsort,理由何在?
qsort 每次对元素进行比较的时候,都要透过 function pointer 去呼叫
compare function。如果你学过 computer architecture 就会了解,使用
function pointer 会比一般的 function call 还慢,尤其 function 的
内容很短的时候,这个额外的负担就占了很大的比例。
因为 C++ 的 sort 是 function template,是在 compile time 就把静
态的 function call 插进 sort 里面,而且若 compare function 很短,
还可以得到 inline 的好处,进一步省掉 function call 的成本,当然
会比 C 的 qsort 快上不少。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.121.115.112
※ 编辑: littleshan 来自: 59.121.115.112 (03/07 13:40)
※ 编辑: littleshan 来自: 59.121.115.112 (03/07 13:41)
1F:推 guest0079:感谢你的意见分享,晚点再来与你讨论 03/07 15:18
2F:推 Ebergies:我认为 guest 的意思是既然 OO 不可避免要产生 overhead 03/07 15:21
3F:→ Ebergies:那乾脆选个不容易 OO 的语言 03/07 15:21
4F:→ Ebergies:如同 public member 总有人要偷用, 那就宣告成 private 03/07 15:22
5F:→ tinlans:「『不可避免』要产生 overhead」? 03/07 15:26
6F:推 Ebergies:我不想争这个... XD 一个 virtual function 你的质疑就倒 03/07 15:28
7F:→ tinlans:原来用 virtual function 是不可避免的,不写会生病死掉。 03/07 15:30
8F:推 Ebergies:没有 virtual 你如何 polymorphism? 还要问别的吗? 03/07 15:31
9F:→ Ebergies:问到最後还算 OO 吗? 03/07 15:31
10F:→ tinlans:当你在 C 有使用 virtual function 相同需求时,你一样要 03/07 15:31
11F:→ tinlans:重新实作跟 virtual function 一样的东西。 03/07 15:31
12F:→ Ebergies:不要跟我说你的 OO 只是一个 class 然後有 method 03/07 15:31
13F:→ Ebergies:放弃掉 OO 就不一定要实作 virtual function 一样的东西 03/07 15:32
14F:→ tinlans:我的 OO 可以搭不是 OO 的东西在一起,所以不会不可避免。 03/07 15:33
15F:→ Ebergies:甚至有的 virtual function 是为了做 factory 用的 03/07 15:33
16F:→ tinlans:没有人规定一个 class 所有 member function 都是 virtual 03/07 15:34
17F:→ Ebergies:我的 OO 可以搭不是 OO 的东西在一起 <= 那我们有抵触吗 03/07 15:34
18F:→ tinlans:OO 搭了不是 OO 的东西只是「非纯 OO」,不是「非 OO」。 03/07 15:35
19F:→ Ebergies:另外我的重点在 "有人" 会乱用, 既然如此乾脆直接避掉 03/07 15:36
20F:→ tinlans:我看过好多人乱用 pointer 耶,为了避掉大家改用 Java 吧 03/07 15:36
21F:→ Ebergies:避掉 OO 不会降 performance, 避掉 C 用 JAVA 就... 03/07 15:37
22F:→ tinlans:但是避掉 OO 会提高你软体维护的成本。 03/07 15:39
23F:→ tinlans:结果就是,现在纯 C 的程式也免不了使用 OO。 03/07 15:40
24F:推 Ebergies:但是今天没有人在谈软体维护的成本啊... 03/07 15:40
25F:→ tinlans:所以台湾没有软体工业存在,因为普遍无法正视事实。 03/07 15:41
26F:推 Ebergies:不过就我所知... 台湾软体公司几乎都是 C++ 的 code 耶.. 03/07 15:42
27F:→ tinlans:现在的使用者需求越来越大,程式越写越大,哪可能免维护。 03/07 15:43
28F:→ Ebergies:呃... 你是不是离题了 XDD 03/07 15:43
29F:→ tinlans:那都是号称 C++ 的 code,打开 source code 看就知道。 03/07 15:43
30F:→ tinlans:核心还是围绕你第二和第三行的推文啊,我只是在说明为什麽 03/07 15:44
31F:→ tinlans:不「乾脆选个不容易 OO 的语言」。 03/07 15:44
32F:→ Ebergies:问题是第二第三行的推文是针对作业系统核心... = =a 03/07 15:45
33F:→ tinlans:若 p 则 q;破 p 可以使命题无效,破 q 可否定命题。 03/07 15:45
34F:→ tinlans:作业系统核心也是需要 OO 的,因为需要维护啊。 03/07 15:46
35F:→ tinlans:很多人被教科书骗了以为 OO 就是要跟现实物体 1 : 1 呈现 03/07 15:46
36F:→ Ebergies:问题是它的复杂跟 OO 与不 OO 没很大的关系 03/07 15:47
37F:→ tinlans:,读过比较深的 OO 书籍都会知道那些说法只是为了让你懂。 03/07 15:47
38F:→ tinlans:有复杂的转型和依赖 union 的地方通常都可以用 OO 漂亮的 03/07 15:48
39F:→ tinlans:解决掉,而且不会产生额外负担,因为你 C 原本就那样写。 03/07 15:48
40F:→ tinlans:实作相同的功能,C++ 带来的额外负担是 C 写就存在的。 03/07 15:49
41F:推 Ebergies:我觉得你没有搞懂话题 (逃) 03/07 15:51
42F:→ Ebergies:你说的大都是正确的 03/07 15:51
43F:→ tinlans:OO 当初被设计出来不是为了「让写程式的人比较直觉」。 03/07 15:52
44F:→ tinlans:只是因为手动维护 type code、union、function pointers 03/07 15:52
45F:→ tinlans:其实有很多风险存在,语言提供 OO 机制反而是绑住你让你不 03/07 15:53
46F:→ tinlans:能太自由去乱搞。 03/07 15:53
47F:→ Ebergies:但问题在於 "有人" 会因为 C++ 方便的功能做出不好的东西 03/07 15:53
48F:→ tinlans:事实上,kernel 甚至其它软体的复杂度常常是这些东西带来 03/07 15:54
49F:→ tinlans:的,所以 C++ 才会避免「有人」乱设 function pointers, 03/07 15:54
50F:→ tinlans:避免「有人」乱填 type code,避免「有人」乱用 union 栏 03/07 15:55
51F:→ tinlans:位。 03/07 15:55
52F:→ tinlans:C 写出比 C++ 危险的东西比率高得多了,C++ 圣经本都讲过 03/07 15:56
53F:推 Ebergies:你讲的部分是"维护"的不好, 我说的是"效能"的不好 03/07 15:56
54F:→ Ebergies:而且没有人在跟你说用 C 写东西比较不危险啊老大... 03/07 15:56
55F:→ tinlans:我 15:48 - 15:49 那三行不是说了,C 写成那样效能也一样 03/07 15:57
56F:→ tinlans:,但是比较危险。 03/07 15:58
57F:→ tinlans:重点是,C 真的有那样的东西存在於 kernel source code。 03/07 15:58
58F:→ tinlans:你用 C++ 的 OO 机制写,是 compiler 帮你产生等效的程式 03/07 15:59
59F:推 Ebergies:你为什麽要忽略一开始的推文呢?... 03/07 15:59
60F:→ tinlans:码,效率上不会比较差,但是又比较安全。 03/07 16:00
61F:→ tinlans:你一开始的推文不是说明为什麽乾脆选个不容易 OO 的语言吗 03/07 16:01
62F:推 Ebergies:我不想从 virtual function 那行又重新再讲一遍... 03/07 16:02
63F:→ tinlans:,既然 kernel 有 OO 可以漂亮解决的程式码,又不会损失效 03/07 16:02
64F:→ tinlans:能,又比较安全,你为什麽不用? 03/07 16:03
65F:→ tinlans:我也不想从手动维护 type code、union、function pointer 03/07 16:03
66F:→ tinlans:这边重讲一遍。 03/07 16:03
67F:→ H45:请问可以回文吗....双方论点我抓不太到 03/07 16:03
68F:→ Ebergies:我没有反驳你这边喔 03/07 16:03
69F:→ tinlans:还是你认为手动维护这些东西带来的效能损失比 virtual 03/07 16:04
70F:→ tinlans:function 少? 03/07 16:04
71F:→ Ebergies:我是说 C++ 提供这些东西, 就有人会乱用 03/07 16:04
72F:→ tinlans:你第二行强调 overhead,15:56 强调「效能」。 03/07 16:05
73F:→ Ebergies:C 乱写会当机, 会不容易维护, C++ 乱写比较不会当机 03/07 16:05
74F:→ Ebergies:但 C++ 乱写带来的 performance down 比较大, 可以理解吧 03/07 16:06
75F:→ tinlans:乱用的部分我也用容易维护和比 C 不易犯错回你了啊。 03/07 16:06
76F:→ tinlans:........所以当机比 performance down 来得好吗? 03/07 16:07
77F:→ tinlans:我推荐 Intel 的 vTune,用过它你就会知道这根本不是问题 03/07 16:07
78F:→ Ebergies:但是作业系统虽然 care 当机,但要写得很安全效能又差太多 03/07 16:07
79F:→ tinlans:,那是一套很强的效能分析器,跑下去你就知道问题在哪了。 03/07 16:07
80F:→ Ebergies:变成你要用 C++ 写还是会写成 C 的形式 03/07 16:08
81F:→ tinlans:不,C 也为了让它安全付出不少代价,这些可以无偿跟 OO 换 03/07 16:08
82F:→ tinlans:我不否认用 C++ 写 kernel 时常要以纯 C 形式撰写,但它的 03/07 16:09
83F:→ tinlans:OO 机制却可以在适当时机发挥效用。 03/07 16:10
84F:推 Ebergies:你是指 attack 的安全还是 bug 方面的安全? 03/07 16:10
85F:→ tinlans:我们不是光就当机这件事为前提讨论是否安全吗? 03/07 16:10
86F:→ Ebergies:所以, 应用软体大多使用 OO 了不是吗? 03/07 16:10
87F:→ tinlans:跟 UI 接近的地方主要使用 OO 是没错的,C++ 在 lib 层偏 03/07 16:11
88F:→ tinlans:好的是静态多型而非动态多型。 03/07 16:11
89F:→ Ebergies:所以最後 release 的结果还是会以纯 C 比较好对吧 03/07 16:12
90F:→ tinlans:纯 C 不是最好的,OO 适用的地方在於「功能抽换」以及模组 03/07 16:13
91F:→ tinlans:跟外界沟通的边界上。 03/07 16:13
92F:推 Ebergies:这我也很同意啊 = = 03/07 16:13
93F:→ tinlans:你可以比较 C++ 写的 kernel 跟 C 写的 kernel 其易读性和 03/07 16:14
94F:→ tinlans:效能,世界上又不是没有 C++ 写的 kernel。 03/07 16:14
95F:推 Ebergies:我所谓选择 C 的原因并不是 C++ 写不出好效能 03/07 16:16
96F:→ Ebergies:而是 C++ 容易写出不好的效能 03/07 16:16
97F:推 tinlans:我知道你说的是 C++ 「不小心」会写出效能不好的东西。 03/07 16:16
98F:→ Ebergies:那我们刚刚是在搞笑吗... ... 03/07 16:17
99F:→ tinlans:不过我倒是不认为有本事用 C++ 写 kernel 的人会这麽呆。 03/07 16:17
100F:→ tinlans:工厂里把几百万的机具搞坏的员工,理由是他嫌操作手册太多 03/07 16:19
101F:推 Ebergies:我以为是只要有心人都可以写 kernel... ... =口= 03/07 16:19
102F:→ tinlans:,这个理由你会接受吗? 03/07 16:19
103F:→ tinlans:你担心的事情只会驻留在某个时间点上,当一个人辛辛苦苦用 03/07 16:20
104F:→ tinlans:C++ 写出 kernel 却发现效能不好时,他会去查原因还是直 03/07 16:21
105F:→ tinlans:接用 C 重写一遍? 03/07 16:21
106F:推 Ebergies:如果写人都是天才, 那基本上... 应该是没什麽差啦... 03/07 16:21
107F:→ tinlans:就算写的人是个笨蛋,随着时间的演进,他也会聪明起来。 03/07 16:22
108F:→ Ebergies:等等~~~ 离题了 XDD 不过我还是可以回答你: 查原因 03/07 16:22
109F:→ Ebergies:但查到最後可能会改掉架构, 然後发现不用 OO 03/07 16:22
110F:→ Ebergies:结果最後居然能用 C compile (大惊!!?) 03/07 16:23
111F:→ tinlans:但是你忽略了当他抛弃 OO 之後可能遇到的新问题。 03/07 16:24
112F:→ tinlans:我也遇过抛弃 OO 改用 C 写才发现 OO 可贵之处的人啊 XD 03/07 16:24
113F:推 Ebergies:... = = 我从以前到现在一直是用 OO 在写程式啊... = = 03/07 16:25
114F:→ tinlans:很多东西在没有了解需求的当下是不知道它的优点和用处的。 03/07 16:25
115F:→ Ebergies:尤其了解 patterns 以後觉得 OO 更是可贵 03/07 16:25
116F:→ tinlans:那你有没有遇过用纯 C 为了某个「弹性」和「安全性」手刻 03/07 16:26
117F:→ tinlans:个半死之後才发现那其实根本就是 OO 的前身(劣化版) 结果 03/07 16:26
118F:→ tinlans:干得要死的情形呢? 03/07 16:26
119F:→ Ebergies:想到 "弹性" 应该直觉就会想到 OO 吧... 我倒是没这经验 03/07 16:27
120F:→ tinlans:有人是绕了一圈才体会到其实所谓的 overhead 根本不存在。 03/07 16:28
121F:→ Ebergies:但是我还是要说追求效率时你会很想把那些弹性全都拆掉... 03/07 16:28
122F:→ tinlans:他当初之所以用 OO 就是考量到这些,结果发现效能不佳丢掉 03/07 16:28
123F:→ Ebergies:有一好无两好就是这样 03/07 16:28
124F:→ tinlans:OO,结果用纯 C 刻出一样的东西来,结果发现效能也一样。 03/07 16:29
125F:→ Ebergies:因为刻一样的东西表示 OO 的概念仍然在只是用 C 实作吧 03/07 16:29
126F:→ tinlans:......然而现实是,少了弹性会让 user 哭,偏偏 kernel 的 03/07 16:30
127F:→ tinlans:user 就是最难搞的 programmer。 03/07 16:30
128F:→ tinlans:可以用 OO 改写又效能无损的 C 有两大类:1. 根本就是 OO 03/07 16:32
129F:→ tinlans:2. OO 书籍上最诟病的那些写法 03/07 16:33
130F:→ tinlans:2. 是回你 16:29 说的部分,说明状况不只有 1. 而已。 03/07 16:34
131F:→ tinlans:无论你怎麽走,requirement 还是长那个样子摆在那边。 03/07 16:35
132F:推 Ebergies:哈哈哈 XD 所以以前 linux 难用有一部分就是这样啊 03/07 16:35
133F:→ tinlans:舍弃 requirement 奔向 performance 的怀抱,结果就是被 03/07 16:37
134F:→ tinlans:user (programmer) 骂到臭头。 03/07 16:38
135F:→ weiyucsie:我怎麽觉得吵这麽多 不如实际改写看看比较实际XD 03/07 17:03
136F:→ weiyucsie:看看实际上会遇到的困难 以及在各方面的比较 03/07 17:04
137F:→ weiyucsie:不过感觉sort那种东西 有点trade off就是了(速度/大小) 03/07 17:05
138F:→ weiyucsie:(不过应该是部分改写 全部改写太累了XD) 03/07 17:21
139F:推 bugmans:改写比较难,笔战比较简单 03/07 18:33
140F:推 yoco315:典型的 Java 言论 XD 03/07 20:09