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


并不是每个问题都需要用C++ 解决 , 也不是说C++ 的每个问题都足够重要 , 值得做一种解决方案 。 例如 , 完全没必要扩充C++ 去直接处理模式匹配或定理证明; C语言著名的运算符优先级的毛病(2.6.2节)也最好让它待在那里 , 或通过警告信息去处置 。
C++ 必须现在就是有用的:许多程序设计是现世的 , 用在功能较差的计算机上 , 运行在相对过时的操作系统和工具上 。 大部分程序员没经过应有的形式化训练 , 几乎没时间去更新他们的知识 。 为了能够为这些程序员服务 , C++ 必须能适合具有平均水平的人 , 能用于平均水平的计算机 。
虽然我也多次想过尝试 , 但我从来就没有真正的欲望去抛弃这些人以获得某种自由 , 去调整我的设计以满足最尖端的计算机和计算机科学研究者们的口味 。
这个规则的意义——与大部分其他规则一样——也将随着时间推移而改变 , 部分地是C++ 成功的结果 。 威力更强大的计算机今天已经可用了 , 更多程序员接受了C++ 所依赖的基本概念和技术 。 进一步说 , 随着人的抱负和期望的增长 , 程序员所面对的问题也在改变 。 这也意味着要求更多计算机资源 , 要求更成熟的程序员的某些语言特征 , 今天已经可以并且应该考虑了 。 异常处理(第16章)和运行时类型识别(14.2节)就是这方面的例子 。
每个特征必须有一种合理的明显实现方式:不应该有必须通过复杂的算法才能正确地或有效地实现的特征 。 理想地说 , 应该存在明显的分析和代码生成策略 , 而这些应该足够应付实际使用 。 如果更多思考能产生更好的结果 , 当然是越多越好 。 大部分特征都通过实现、试验性的使用、检查修订 , 而后才被接受 。 那些没能按这种方式去做的地方 , 例如模板的实例化机制(15.10节) , 后来就暴露出了一些问题 。
当然 , 使用者总比写编译器的人多得多 , 所以 , 如果在编译复杂性和使用复杂性之间出现了需要权衡的问题 , 解决方案必定是偏向用户的 。 我在许多年做编译器维护的工作中 , 已经真正理解了这个观点 。
总提供一条转变的通路:C++必须逐渐成长 , 以便很好地服务于它的用户 , 并从用户的反馈中获益 。 这里隐含着特别关注和保证老代码能继续使用的问题 。 当某种不兼容性已经无法避免时 , 需要特别关注如何帮助用户更新他们的代码 。 类似地 , 必须提供一条路径 , 使人能从容易出错的C一类的技术转到C++的更有效的使用方面来 。
要清除一种不安全、容易出错 , 或者简单说就是有毛病的语言特征 , 最一般的策略是首先提供一种更好的替代品 , 而后建议人们避免使用老的特征或技术 , 而只有到数年之后——如果需要做的话——再删除那个有问题的特征 。 可以有效地通过让编译产生警告信息的方式支持这种策略 。 一般说 , 直接删除一个特征或者更正一个错误是不可行的(典型原因是为了保持与C的兼容性):替代的方法是提出警告(2.6.2节) 。 这样做 , 还能使C++ 的实现比仅根据语言定义看到的情况更安全些 。
C++是一种语言 , 而不是一个完整的系统:一个程序设计环境包含了许多部分 。 一种方式是将多个部分组合成一个“集成化的”系统 , 另一种方式是维持系统中各部分之间的经典划分 , 例如编译器、连接器、语言的运行支持库、I/O库、编辑器、文件系统、数据库 , 等等 。 C++ 遵循的是后一条路 。 通过库、调用约定等 , C++ 能适应各种系统里指导着语言和工具之间互操作的系统规定 。 对于移植和实现的简单性 , 这些都是非常关键的 。 更重要的 , 对支持不同语言写出的代码之间的互操作 , 这些做法也很关键 。 这种方式也能允许工具的共享 , 使作为个人的程序员能更容易地使用多种语言 。
C++ 的设计就是准备作为许多语言之中的一个 。 C++ 支持工具的开发 , 但又不强求某种特定的形式 , 程序员仍然有选择的自由 。 这里的关键思想是 , C++ 及其关联工具应该对给定系统有正确的“感觉” , 而不是对于什么是一个系统 , 或者什么是一个环境强加上某种特殊的观点 。 对于大型系统 , 或者有着不同寻常的约束的系统而言 , 这些非常重要 。 这类系统常常无法得到很好的支持 , 因为“标准的”系统的设计总是倾向于专门支持个人 , 或者是支持很小的组 , 仅仅支持他们做相当“普通的”工作 。