新的C语言: C99标准介绍
Randy Meyers
此篇文章摘取与即将登载于《Dr.Dobb's 软件研发》》第二期(2003年9月)的《新的C语言,C99标准介绍》,文章主要是介绍了C99的新特性,在得到作者Randy Meyers以及《Dr.Dobb's 软件研发》》负责人刘江先生的应允下,把全文的前面的一部分作为文档发表,希望能对大家有所帮助。
译注2:C语言的产生源于失败的项目---Multics。从70年代初期的早期C语言到后来的K&R C,ANSI C,C89,在将近20年中C语言多次发展演化,一直到1999年C语言又重新定案,成为新的C语言标准。这篇文章发表在CUJ Octorber 2000 V18 N10,当时C99标准刚刚公布一年,C社区正急需正统的声音。本文作者Randy Meyers作为标准委员会委员,在CUJ杂志开了一个专题系列The New C用来讨论新标准的新特性,本文就是其中的第一篇。本文从全局上介绍了新标准C,尤其是一些增加的特性,期望本文能给关心C语言和使用C语言的用户带来帮助。在翻译上,所有译者在翻译过程中有疑惑的术语或者其他一切都以括号形式把原文直接给出,诚心不想给读者半点误导,但是否如愿还需读者的评判,关于本文的一切可以用[email protected]与译者联系和讨论。
C99很像C89,很多地方是一致的,但更多的却是不同。
简介
你可能没有注意到,针对ANSI/ISO C的主要的修订版[1] 在去年12月已经被核准通过,那是就C99。同样的,你可能也没注意到,其实你已经在使用这个新的C语言了,或者至少用到它的一部分。这需要归功于标准委员会在接受新特性到C语言的过程中采取了恰当而保守的方式。差不多所有的新特性早已经被实现并且在现存的一些C编译器(impletmentations)中证明了其存在的价值。虽然没有编译器能保证全部的C99特性,但其中许多在很多年前就实现了C99中不同的部分。这对于C程序员来说将是个好消息。或许你曾经为了保证程序的可移植性而在你喜爱的编译器里避免使用一些独立的特性,但现在如果这些特性是C99中的一部分的话,你可以放心的使用这些特性,因为他们将在大部分遵守C99标准的编译器中被保证。毫无疑问,新标准是向上兼容旧的,当然也会有些不兼容地方,但这些都是非常少而次要的。标准委员会非常努力地工作就是为了将和老版本的兼容性问题所带来的影响减少到最小。从后面讨论到的关键字你可以看到这方面的例证。
命名和历史
程序设计语言随着时间在不断演进,语言的命名方式不仅仅依赖于语言本身的名字,还结合了它们被定义的年代。(回到五年前,ALGOL 68, C89, Fortran 77还有Fortran 4,我对这些名字真的感到好笑,如今这些令人讨厌的命名方式还带来了千年虫问题,04将无法区别眼前的2004或者久远的1904)。新的C语言和定义它的新标准被称为C99,而原来的C语言标准[2]被称为C89或者C90(ANSI在1989年公布了标准文档而ISO在1990年重新编排了标准文档章节后才公布)。如果你在自己的程序中处理过日语,韩语,或者中文的文字问题你也许会知道对于C89来说曾经有一次小的升级[3]被称为C95,这次升级主要是加入了更多的用来处理多字节和宽字节字符(wide and multibyte characters)的库函数(Java的倡导者曾经错误的宣布Java是第一个支持大字符集合的语言,其实这样的支持在C89中就已经存在了)。
对于C99施加影响最大的或许就是数值C语言扩展小组(Numerical C Extensions Group, or NCEG.)。NCEG是ANSI C标准委员会J11的一个子委员会,他们主要在C89完成后从事技术报告工作[4]。NCEG的技术报告不是标准,它只是号召编译器实现者来体会并且得到那些一系列描叙清楚的语言特性的经验。这些扩展中大的部分是用来处理C语言数值编程的(IEEE arithmetic, complex numbers),但是还有一些是为了其他一般目标或者性能的提升和优化(变长数组,并行处理,restrict关键字)。
NCEG的扩展一些是由子标准委员会首次定义的,而其他一些则是根据编译器厂商对于已经实现的特性的反馈而重新定义的。所以技术报告不是标准,编译器厂商可以自由的选取并且实现这些扩展,甚至可以根据用户的经验更改这些扩展。
真实世界的需求是非常有价值的。语言的不同特性在内部会以一种令人吃惊的方式相互作用,而有的特性将会给程序的运行效率带来不良影响,即使这些特性永远都不会被用到(举例来说,在一些C++的实现中,使用少量多继承的程序将会比只使用单继承的程序慢一些)。NCEG的扩展实验不仅仅是为了改进扩展本身,同时是为了改进它们的规格,并且让标准委员会对于那些已知的语言特性的内部作用和价值保持信心。
哪些不属于C99
并不是所有的NCEG扩展都被C99所接受,其中最大的例子也许就是NCEG对并行处理的支持并没有被C99所接受。这些并行处理是基于Thinking Machines上的C*语言(读作C-Star)的。并行计算机制造商为了能让程序员写出清晰的并行程序代码而做出许多不同的扩展特性,而NCEG技术报告对此却没有做出改进,所以仍然没有一致的并且是最好的方式在并行计算机上编程。因此,这样的特性是不适合被标准C语言接受的。另外一些NCEG扩展在被加入到C99之前做了一些更改。NCEG支持的复数包含分开的虚数数据类型(separate imaginary datatypes)。比如,double_ imaginary数据类型。但是在C99中虚数数据类型却是可选择的。
然而,被考虑得最多到最后却没有被C99采纳的特性不是来自NCEG,而是C++。在将近一年的时间里,标准委员会一直在从事C++中的子集--面向对象特性的研究工作。这个子集有点像80年代末的C++特性的混合,包括单继承(非多继承),虚函数,成员访问控制(公有,私有,保护),构造函数,析构函数。如果新的C语言与早期的C++相似可以说是既有进步也有退步。积极的一面是,这些特性对于初期C++的流行起到了巨大作用,到现在这些特性的价值和它们之间的内在作用已经被大家很好的理解,而且已经证明它们是可以共存的。然而,消极的一面是“90年代的C++是否可以看作是80年代的C++的自然演化?如果是, C采用80年代的C++的特性价值何在?要知道我们已经拥有90年代的C++了。”最终,多方面的原因,包括一些逻辑上的,让标准委员会拒绝把面向对象特性加入到C语言中去。
Randy Meyers is consultant providing training and mentoring in C, C++, and Java. He is the current chair of J11, the ANSI C committee, and previously was a member of J16 (ANSI C++) and the ISO Java Study Group. He worked on compilers for Digital Equipment Corporation for 16 years and was Project Architect for DEC C and C++. He can be reached at [email protected].
本文地址:http://com.8s8s.com/it/it29114.htm