C++之父谈C++语言设计规则( 九 )


4.5 低级程序设计支持规则很自然 , 上面提出的规则基本上都适用于所有语言特征 。 下面的规则也同样影响C++ 如何作为一种表述高层设计的语言 。
C++之父谈C++语言设计规则文章插图
使用传统的(笨[1])连接器:初始目标就包括了容易移植 , 容易与用其他语言写的软件互操作 。 强调C++ 应该可以用传统连接器实现 , 就是为了保证这些东西 。 要求通过在Fortran早期就有的连接技术必然是一件很痛苦的事情 。 C++ 的一些特征 , 特别是类型安全的连接(11.3节)和模板(第16章)都可以用传统的连接器实现 , 但如果有更多的连接支持 , 它们还可以实现得更好 。 C++ 的第二个目标就是想推动连接器设计的改革 。
采用传统连接器 , 使维持与C的连接兼容性变得相对简单 。 对平滑地使用操作系统功能 , 使用C和Fortran等 , 使用库 , 以及写为其他语言所用的库代码 , 这一特性都具有本质性 。 对于写想作为系统底层部分的代码 , 例如设备驱动程序等 , 使用传统连接器也是最关键的事情 。
没有无故的与C的不兼容性:C语言是有史以来最成功的系统程序设计语言 。 数以十万计的程序员熟悉C , 现存的C代码数以十亿行计 , 存在着集中关注C语言的工具和服务产业 。 而且C++ 又是基于C的 。 这就带来一个问题:“C++ 的定义在与C相匹配方面到底应该靠得多么近?”C++ 不可能把与C的100% 兼容作为目标 , 因为这将危及它在类型安全性和对设计的支持方面的目标 。 当然 , 在这些目标不会受到干扰的地方 , 应该尽量避免不兼容性——即使这样做出的结果不太优雅 。 在大部分情况下 , 已经接受的与C语言的不兼容性 , 都出现在C规则给类型系统留下重大漏洞的地方 。
在过去这些年里 , C++ 最强的和最弱的地方都在于它与C的兼容性 。 这种情况不奇怪 。 与C兼容性的强弱将来也一直会是一个重要议题 。 在今后的年代里 , 与C的兼容性将越来越少地看作是优点 , 而更多变成一种义务 。 必须找到一条发展的道路(第9章) 。
在C++ 之下不为更低级的语言留下空间(除汇编语言之外):如果一个语言的目标就是真正成为高级的——也就是说 , 它想完全保护自己的程序 , 使之避开基础计算机中丑陋且使人厌倦的细节——那么它就必须把做系统程序设计的工作让给其他语言 。 典型情况下 , 这个语言就是C 。 但另一种情况也很典型 , C在许多领域中将取代这种高级语言 , 只要在这里控制或速度被认为是最关键的问题 。 常见情况是 , 这最终将导致整个系统完全用C语言来编写;或者是导致这样的一个系统 , 只有对两种语言都非常熟悉的人才能够把握它 。 在后一情况下 , 程序员常常会遇到一个艰难的选择:给定的任务究竟适合在哪个层次上做程序设计呢 , 他不得不同时记住两种语言的原语和准则 。 C++ 试图给出另一条路 , 它同时提供了低级特征和抽象机制 , 支持用这两种东西构造混合的系统 。
为了继续成为一种可行的系统程序设计语言 , C++ 必须保持C语言的那种直接访问硬件、控制数据结构布局的能力 , 保有那些能以一对一的风格直接映射到硬件的基本操作和数据结构 。 这样 , 它的替代品就只能是C或者汇编语言 。 语言设计的工作就是去隔离这些低级特征 , 使不直接操作系统细节的代码不需要用这些低级特征 。 这里的目标是保护程序员 , 防止出现无意中越界的偶然的错误使用 。
对不用的东西不需要付出代价(0开销规则):对于规模较大的语言 , 有一种论断人人皆知 , 说它们会产生大而慢的结果代码 。 最常见的是由于支持某些假设的高级特征而产生的额外开销 , 而这种开销又散布在整个语言的所有特征中 。 例如 , 所有对象都需要扩大 , 以保存为某种系统簿记而使用的信息;对所有数据都采用间接访问方式 , 因为某些特征通过间接访问特别容易管理;或是对各种控制结构都进行加工 , 以迎合某种“高级控制抽象” 。 对C++ 而言 , 这类“分布式增肥”根本就不合适 , 接受它就会在C++ 之下为更低级的语言留下空间 , 使得对那些低级和高性能的应用而言 , C语言将成为比C++更好的选择 。