当 Richard Appiah Akoto 在加纳一所学校的黑板上画出 Microsoft Word 用户界面的教学图时,他迅速在社交媒体上走红https://news.microsoft.com/apac/2018/03/17/teacher-who-used-a-chalkboard-in-computer-class-because-he-had-no-computer-stars-at-microsofts-education-exchange/。他的学校资源匮乏,没有可用的电脑,只有一块普通黑板,但这并没有阻止他履行教师的职责。他以极具创意的方式尽最大努力向学生传授可能改变他们生活的知识,希望这些知识有朝一日能帮助他们追求更好的生活。
这已经成为一段励志的历史,但真正值得我们思考的问题是:在黑板上教授 Microsoft Word 是标准做法吗?
让我们回到最初的目标:我们要探讨的是 C++ 程序的标准合规性问题。
对于一些狂热的 C++ 开发者来说,C++ 最新标准就像一本神圣的经文,其中每一个关键字、每一条语法规则都必须严格遵守。任何偏离标准的行为都被视为“异端” —— 要么重写为符合标准的代码,要么其作者将视为“遗留代码维护者”,贴上某种技术落后的标签。
然而,现实往往并不那么理想主义。许多开发者根本无法使用最新的 C++ 标准。这可能是由于他们的工作依赖于特定项目所绑定的老旧编译器,而这些编译器不支持现代特性;也可能是他们所处的开发环境,限制了某些语言功能的使用。
又或者,他们受雇于某个平台,该平台在过去二十年中从未进行过更新。原因可能是该平台的供应商早在十年前就已破产,也没有人接手后续的维护工作。但由于系统仍在正常运行并持续产生收入,因此它依然由 20 年前的技术栈支撑着,用着当时可用的工具进行维护。
这种情况下,显然不可能配备支持最新 C++ 标准的编译器。那么,是否意味着这些平台上开发者的 C++ 代码就不符合标准呢?
让我带你们回到本章作者亲身经历的一个真实场景。在世纪之交,我还是大学里一名计算机专业的学生,参加了一门名为《C++ 编程入门》的课程。那是学校唯一开设的 C++ 相关课程,一位老师拿着一本书,面对三十多位学生授课。
街角复印店的老板对此感到非常高兴,因为有一天,老师决定把这本书借给其中一个学生复印。那本书是 Kris Jamsa 所著《C/C++ Developer's Bible》的本地化翻译和简化版,我们亲切地称它为“斑点狗书”。
这个版本仅保留了 C++ 部分内容,但附带了一张极为重要的插图:展示了 Turbo C++ Lite IDE 及其配套编译器,打包在一个标准容量为 1.44MB 的软盘上。对于不太熟悉这个名字的读者来说,Turbo C++ Lite 是 Borland 公司广受欢迎且用户友好的 IDE 和编译器 Turbo C++ 的精简版本。虽然核心编译器仍然相同,但为了将整个开发环境压缩进一张软盘,很多附加功能和工具都移除了。
这是我们第一次接触到编译器、链接器,以及语法复杂世界的起点。对其中一些人来说,这段经历如此迷人,以至于即使过了二十年,我们今天仍在日常工作中使用 C++。因此,我们的第一个 C++ 程序,看起来与下面这张截图中的程序非常相似。
哦,你脸上的表情!亲爱的 C++ 爱好者,我能清楚地想象出你此刻的心情:
面对这一切,你也许会想要放弃理解其中的原因,长叹一口气,转身离开。但请稍等 —— 让我们一起深入这段“历史遗迹”,看看它背后到底发生了什么故事。
我们所处的学习环境,与 Richard Appiah Akoto 所面临的困境有着惊人的相似之处。在我们的教育阶段,也只有一间配备黑板的教室、一位敬业的老师、一本教材,以及几本辅助书籍相伴。即便如此,我们依然学会了 C++。
从标准的角度来看,这或许是一个理想的学习环境:C++ 标准本身非常宽松,它并不要求现代计算机中常见的那些设施 —— 不需要硬盘、不需要图形界面,甚至不需要操作系统。事实上,唯一真正严格的要求是 char 的大小必须至少为 8 位,以确保它可以容纳基本执行字符集中的每一个字符(包括标准 ASCII 字符)。此外,C++ 标准还保证了 sizeof(char) == 1,无论其是有符号还是无符号类型。其余的一切,都是建立在这个基础之上的。
因此可以说,在我们被允许进入计算机实验室之前,我们所处的环境正是学习标准 C++ 的理想场所。没有恼人的系统依赖,没有因硬件问题导致的崩溃,也没有因代码无法编译而产生的挫败感。由于我们无法在黑板上运行编译器,老师很快意识到,试图在黑板上演练复杂的 C++ 代码并不现实。于是,我们被安排在每周五清晨进入计算机实验室进行实际操作,但真正的挑战也正是从那一刻开始的。
事情其实很简单:你可能难以想象,当年我们学校用于教授 C++ 的计算机实验室里,竟然只有一排 80286 IBM AT 兼容机。
没错,你没看错。三十名学生共享八台计算机,每台都搭载着当时可能是“高科技”的 80286 处理器 —— 尽管在一年半之后它就已经过时了。这些机器很可能是某家完成升级的企业或援助组织捐赠给学校的旧设备,目的是为了获得一些税收减免。每台电脑前挤着四到五个人,手中拿着那本唯一的教材和几张复印页,试图在这有限的资源中掌握一门强大的编程语言。
虽然情况不像二十年后 Richard Appiah Akoto 所面对的那样艰难,但说实话,条件也好不到哪去。这些机器只能运行纯 DOS 系统,而我们能用的最好的编译器,就是十多年前发布的 Turbo C++ Lite。那么,这是否意味着我们有意地在学习编写非标准的 C++ 代码?显然不是。我们只是在当时的条件下,尽可能地写出我们能够写出的代码。
不过,让我们把时间拉回到更近一些。截至 2024 年(本书撰写之时),Stack Overflow (https://sackoverflow.com/) 上仍有 46 个问题包含那个令人熟悉的“罪恶”短句:void main(void)。最新的一个提问甚至出现在 2023 年。
至于 iostream.h,相关内容更多一些,且主要出现在教学场景中。而在这种环境中,如果不使用 using 指令或命名空间限定符就尝试使用 cout,那几乎注定是徒劳的。那么问题来了:在 2024 年的今天,是否仍然有开发者在编写依赖于非标准 C++ 的代码?或者,是否还有学生正在以非标准的方式学习 C++?
进一步浏览 Stack Overflow,你会发现另一个有趣的“古董级”C++ 方言:conio.h。这个头文件早在 C++ 正式标准化前几年就随着 Turbo C 和 Turbo C++ 一起发布。然而,考虑到 2024 年仍有年轻开发者在询问它的用法,我们可以合理推测,前面的问题的答案很可能是肯定的。
根据他们的具体处境和可能性 —— 无论是不得不用黑板学习、用粉笔画出代码结构,还是在一台老旧机器上共享键盘、彼此轻轻拍打着手敲下每一行代码 —— 在当今世界,仍有一些开发者被迫接受一种非标准的 C++ 学习和开发方式,而这可能并非出于他们自愿的选择。