C语言从语言角度上讲,最大缺陷在于要求程序员自己去做内存管理。用C语言去处理复杂的数据结构,程序员大部分的时间都花在了这上面,并且滋生了无数Bug。调试C程序变成了一项独立于编写C程序的技能。防止缓冲区溢出、防止数据读写越界、正确的动态回收内存、避免悬空指针,这些在大部分语言看起来不可思议的关注点,在C语言程序员眼里变得稀松平常,甚至是衡量C程序员技能经验水平的重要标志。可要知道,这些和具体问题的解决过程无关。
也有人试图在C语言层面解决这个问题,例如以库形式提供垃圾回收的机制(我也曾做过类似尝试)。但C语言本身的设计使它无法成为一个完美的解决方案。同样的问题也存在于C++。现在看来,不对语言做大的改造,很难回避。可改造本身又违背了C语言一贯的哲学。C语言的发明人之一的Ken Thompson近年来参与了Go语言的设计和实现,可以看成从另一角度对新的程序开发语言的尝试,可那已经不是C。
这个问题在一定程度上也促使了Java的诞生。Java采用虚拟机和字节码的方式改造了底层的机器模型,并在底层模型的基础上加入了垃圾回收机制,并在语言层面取消了指针。在C语言的原生地,也有更多的动态(脚本)语言出现。先是有Awk这样的简易语言,后有Perl,再是Python等的流行。在Unix风格下,程序员倾向于为特定领域设计特定的语言。C和Unix的设计哲学是一体的。它们都鼓励清晰的模块化设计,让模块之间独立,再用薄的胶合层联系起来。脚本语言在现代类Unix系统上大量出现并充当这种粘合工作就是一种发展必然。而原本的充当粘合部分的脚本语言,也逐步发展起来,远远超出脚本的用途范畴。作为程序员,尤其是C程序员,必须对它们有所了解并掌握其中的一些,才能适应现代的挑战。
我们不应该指望一门语言解决所有的问题。至于C语言本身,它将在很长的一段时间,带着它的优雅和缺陷,继续扮演它在计算机世界中重要的角色。
作者简介:
云风,网易杭州研究中心总监,在网易从事网络游戏开发十年。早年独立完成开源2D游戏引擎“风魂”,并用于网易西游系列游戏至今。近年来主要从事3D游戏引擎的研发,以及网络游戏服务器的架构设计。有近20年C语言软件开发经验。Blog网址:http://blog.codingnow.com