LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: liuqionline

为什么到现在为止 UNIX 系统中的主流编程语言是 C 而不是 C++

[复制链接]
发表于 2004-4-6 12:19:33 | 显示全部楼层
“C++不能分配内存”

请指点
发表于 2004-4-7 05:27:10 | 显示全部楼层
OO is not silver bullet. From the practice on Unix programming,
lots of hackers recognized that OO fits for Game, GUI framework,
and C++ is "overqualified" for most application.

Please refer to "The Art of Unix Programming" by ESR
发表于 2004-4-12 21:25:57 | 显示全部楼层
让我们听听Bjarne的回答吧。:-)

==========================================
ajs提问:使用C++进行系统编程(systems programming)

长期以来,C一直是UNIX世界系统编程语言,而且仍将如此。我知道您不愿意对语言进行比较,所以我只问问您,是否有什么本质的原因,使得C++无法成为一门优秀的系统编程语言,或者说,不能引起C系统程序员的兴趣?

Bjarne:让“老家伙”学习新技术是件难事儿。

Unix是25年前编写的(我第一次用它是在1973年)。它所有的接口都定义为C函数调用、数组以及结构(structs)。到C++可用的时候,C语言几乎唯我独尊的传统已经持续了10多年了。

Unix程序员没有什么合理的借口避免使用C++,相反,倒是有一些很好的理由去使用它。然而,有数不清的“不使用C++”的借口被提了出来,让我来列出几条:

C++速度慢

C++产生“臃肿的”代码

缺乏优秀的C++编译器

C++太复杂

C++没有为系统程序员提供很多便利条件

C++的高级特性不适于系统编程

C++代码不可移植

C++没有ABI(application binary interfaces,应用二进制接口)

这些借口要么荒谬至极,要么很大程度上无关紧要。其中一些原因对于某些系统(比如缺少合适的C++工具的微型嵌入式系统)来说有一点道理,但对于 Unix/Linux绝非如此,我将简要地解释一下原因。当然了,完整的讨论需要几百页纸头,因为单单举反例是不可能的,换句话说,想证明“对某人来讲没有什么问题不可以解决”是不可能的。

对于同样的程序,C++可以产生与C同样优秀的代码,尽管去试吧!

C++就是被设计用来做那些事情的,当前交付的编译器都遵守这个承诺。

当然了,使用任何语言你都能写出糟糕的程序。C++虽然是一个强大的工具,但对它的误用也会产生明显畸形而臃肿的代码。这可以和那些拙劣的程序员使用C语言编写的“传统的意大利面条”相“媲美”。要注意,一名优秀的C程序员并不会自动成为一名优秀的C++程序员。许多问题都是这么冒出来的:某些优秀的C程序员总是想当然地以为自己随便学点C++语言特性,一周之内摇身一变就成了C++高手。

在一周之内C程序员的确可以从C++中获益,但这仅局限于C++功能的一个子集和库。

C++支持许多威力强大的技术,而这些技术在C中顶多只有微弱的支持,它们学起来是需要时间的。C程序员或许还清楚地记得成为“大师级”C程序员花了他们多少时间。为什么成为一名“大师级”的C++程序员花费的时间就要短一些?我想不出任何理由。

当前一代的C++编译器在符合标准方面远胜于几年前的编译器,但优化器(optimizers)却与C共享。这可能会导致问题,因为它排除了某些不适合C语言的有意义的优化,不过,至少与C共享编译器的大部分,却也能使那些怀疑C++是否可以产生与C等价的代码的人们打消疑虑。

我将在对问题9的回答中探讨语言复杂性的根源。在此,我想指出的是,C++的许多功能可以直接帮助人们编写出高效、可靠且可维护的代码,假如你不去用这些功能,你很可能最终需要利用低阶语言结构模拟实现它们。

甚至那些“新的”或者“高级的”C++特性,例如模板、异常以及运行时类型信息(RTTI),也遵从“零开销”设计原则。假如你需要这些特性,在一个现代的编译器中使用它们比使用C语言来仿造这些功能更加高效(在运行时间和内存空间两方面皆然)。我还没有听说任何C++语言功能在某些系统或嵌入式应用中“没有用”或“负担不起”。

当然了,如果你不需要某种特性(RTTI往往用不着),或某种特性在特定情境下不适用(我可以想出一些不适用异常(exceptions)的程序),你不用它们就是了。“零开销”原则允许你做出这样的决策。这和“在一个给定的应用中不使用某种不适当的C语言特性(例如在一些嵌入式系统中禁止使用 malloc())”没什么两样。

C++具有和C一样的移植性。两种情况下,你都需要对“系统依赖性”进行封装以便移植。大型程序可以在Unix平台之间而移植,某些程序还可以跨越其他平台进行移植。这些技术广为人知,而且当它们应用情况良好时,C++在“将无痛移植的系统概念进行正式化”的方面,甚至具有一个优势。要想看一个例子,你可以参考“定义ACE平台”的C++库(我的C++网页上有链接)。

C++缺乏二进制接口(ABI),最难解决的技术问题可能非此莫属了。C也没有ABI,但在绝大多数(或者全部?)Unix平台上,都有一个“占支配地位”的编译器,其他编译器要想“有用”,都必须遵守它的调用约定和结构布局规则。在C++中,则有更多的“变数”,例如虚函数表(virtual function table)的布局,因此没有任何厂商被批准为C++创建“所有竞争厂商都必须遵守”的ABI。同样道理,以前连接(link)由两台不同PC上的C编译器所产生的代码也是不可能的,所以通常也不可能连接两个不同Unix C++编译器产生的代码 — 除非有兼容性开关。

目前的解决方案通常是将“使用单一的编译器”与“提供C级别的接口”二者结合使用,这并不理想,请参考我对问题10的回答。

也就是说,我认为最主要的问题在于“教育”。对于“C++是什么”以及“它能用来做什么”,很多人的看法严重错误。错误的看法往往累积成学习的严重障碍。现在的C++与1985年的第一版相比已经大相径庭,C++的ISO标准于1998年被批准。对我来说,目前的编译器已足够接近标准。我可以将那些利用较新功能的程序,在编译器之间进行移植,以便在多种平台上进行性能测试,这其中标准库功不可没。
发表于 2004-4-12 21:26:09 | 显示全部楼层
让我们听听Bjarne的回答吧。:-)

==========================================
ajs提问:使用C++进行系统编程(systems programming)

长期以来,C一直是UNIX世界系统编程语言,而且仍将如此。我知道您不愿意对语言进行比较,所以我只问问您,是否有什么本质的原因,使得C++无法成为一门优秀的系统编程语言,或者说,不能引起C系统程序员的兴趣?

Bjarne:让“老家伙”学习新技术是件难事儿。

Unix是25年前编写的(我第一次用它是在1973年)。它所有的接口都定义为C函数调用、数组以及结构(structs)。到C++可用的时候,C语言几乎唯我独尊的传统已经持续了10多年了。

Unix程序员没有什么合理的借口避免使用C++,相反,倒是有一些很好的理由去使用它。然而,有数不清的“不使用C++”的借口被提了出来,让我来列出几条:

C++速度慢

C++产生“臃肿的”代码

缺乏优秀的C++编译器

C++太复杂

C++没有为系统程序员提供很多便利条件

C++的高级特性不适于系统编程

C++代码不可移植

C++没有ABI(application binary interfaces,应用二进制接口)

这些借口要么荒谬至极,要么很大程度上无关紧要。其中一些原因对于某些系统(比如缺少合适的C++工具的微型嵌入式系统)来说有一点道理,但对于 Unix/Linux绝非如此,我将简要地解释一下原因。当然了,完整的讨论需要几百页纸头,因为单单举反例是不可能的,换句话说,想证明“对某人来讲没有什么问题不可以解决”是不可能的。

对于同样的程序,C++可以产生与C同样优秀的代码,尽管去试吧!

C++就是被设计用来做那些事情的,当前交付的编译器都遵守这个承诺。

当然了,使用任何语言你都能写出糟糕的程序。C++虽然是一个强大的工具,但对它的误用也会产生明显畸形而臃肿的代码。这可以和那些拙劣的程序员使用C语言编写的“传统的意大利面条”相“媲美”。要注意,一名优秀的C程序员并不会自动成为一名优秀的C++程序员。许多问题都是这么冒出来的:某些优秀的C程序员总是想当然地以为自己随便学点C++语言特性,一周之内摇身一变就成了C++高手。

在一周之内C程序员的确可以从C++中获益,但这仅局限于C++功能的一个子集和库。

C++支持许多威力强大的技术,而这些技术在C中顶多只有微弱的支持,它们学起来是需要时间的。C程序员或许还清楚地记得成为“大师级”C程序员花了他们多少时间。为什么成为一名“大师级”的C++程序员花费的时间就要短一些?我想不出任何理由。

当前一代的C++编译器在符合标准方面远胜于几年前的编译器,但优化器(optimizers)却与C共享。这可能会导致问题,因为它排除了某些不适合C语言的有意义的优化,不过,至少与C共享编译器的大部分,却也能使那些怀疑C++是否可以产生与C等价的代码的人们打消疑虑。

我将在对问题9的回答中探讨语言复杂性的根源。在此,我想指出的是,C++的许多功能可以直接帮助人们编写出高效、可靠且可维护的代码,假如你不去用这些功能,你很可能最终需要利用低阶语言结构模拟实现它们。

甚至那些“新的”或者“高级的”C++特性,例如模板、异常以及运行时类型信息(RTTI),也遵从“零开销”设计原则。假如你需要这些特性,在一个现代的编译器中使用它们比使用C语言来仿造这些功能更加高效(在运行时间和内存空间两方面皆然)。我还没有听说任何C++语言功能在某些系统或嵌入式应用中“没有用”或“负担不起”。

当然了,如果你不需要某种特性(RTTI往往用不着),或某种特性在特定情境下不适用(我可以想出一些不适用异常(exceptions)的程序),你不用它们就是了。“零开销”原则允许你做出这样的决策。这和“在一个给定的应用中不使用某种不适当的C语言特性(例如在一些嵌入式系统中禁止使用 malloc())”没什么两样。

C++具有和C一样的移植性。两种情况下,你都需要对“系统依赖性”进行封装以便移植。大型程序可以在Unix平台之间而移植,某些程序还可以跨越其他平台进行移植。这些技术广为人知,而且当它们应用情况良好时,C++在“将无痛移植的系统概念进行正式化”的方面,甚至具有一个优势。要想看一个例子,你可以参考“定义ACE平台”的C++库(我的C++网页上有链接)。

C++缺乏二进制接口(ABI),最难解决的技术问题可能非此莫属了。C也没有ABI,但在绝大多数(或者全部?)Unix平台上,都有一个“占支配地位”的编译器,其他编译器要想“有用”,都必须遵守它的调用约定和结构布局规则。在C++中,则有更多的“变数”,例如虚函数表(virtual function table)的布局,因此没有任何厂商被批准为C++创建“所有竞争厂商都必须遵守”的ABI。同样道理,以前连接(link)由两台不同PC上的C编译器所产生的代码也是不可能的,所以通常也不可能连接两个不同Unix C++编译器产生的代码 — 除非有兼容性开关。

目前的解决方案通常是将“使用单一的编译器”与“提供C级别的接口”二者结合使用,这并不理想,请参考我对问题10的回答。

也就是说,我认为最主要的问题在于“教育”。对于“C++是什么”以及“它能用来做什么”,很多人的看法严重错误。错误的看法往往累积成学习的严重障碍。现在的C++与1985年的第一版相比已经大相径庭,C++的ISO标准于1998年被批准。对我来说,目前的编译器已足够接近标准。我可以将那些利用较新功能的程序,在编译器之间进行移植,以便在多种平台上进行性能测试,这其中标准库功不可没。
发表于 2004-4-12 21:29:49 | 显示全部楼层
一不小心就发了两遍,真是惭愧呀?论坛应该设计一个功能,让用户可以删除自己发的帖子嘛,这样就少了很多尴尬了。:-)
发表于 2004-4-12 21:57:01 | 显示全部楼层
最初由 zonzi 发表
因为c可以手动分配内存(malloc,free....),c++(好像没有)不行,....


C++用new和delete分配堆内存,也可以用malloc,free
发表于 2004-4-13 14:11:19 | 显示全部楼层
我认为C++的问题在于比C难学。
同时有误导复杂化的倾向而已。
发表于 2004-4-13 14:15:46 | 显示全部楼层
同意楼上的说法
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表