C语言标准的那些事
C语言的标准
我们在使用C语言编程时很少有人告诉我们C语言各个标准的情况,于是我们在看见一些函数标定支持的C标准(例如仅支持C99及以后),内心不会有什么波澜。
我们常见这些C标准:K&R C、ANSI C、ISO C、C89、C99、C11、C18。让我们补充点可能很少使用的知识吧。
什么是K&R C?
1978年,丹尼斯•里奇(Dennis Ritchie)和布莱恩•柯林汉(Brian ernighan)合作出版了《C程序设计语言》的第一版。书中介绍的C语言标准也被称作“K&R C”。
最初的C标准与我们现在用的有较大差别,例如它竟然还不支持void类型!
什么是ANSI C、ISO C、C89、C90标准?
随着C语言使用得越来越广泛,出现了许多新问题,人们日益强烈地要求对C语言进行标准化。1983年,美国国家标准协会(ANSI)组成了一个委员会,X3J11,为了创立 C 的一套标准。经过漫长而艰苦的过程,该标准于1989年完成,这个版本的语言经常被称作ANSI C,或有时称为C89(为了区别C99)。在1990年,ANSI C标准(带有一些小改动)被美国国家标准协会(ANSI)采纳为ISO/IEC 9899:1990。这个版本有时候称为C90或者ISO C。综上,ANSI C、ISO C、C89、C90其实是同一种标准。
这一版本的C就更接*我们*常使用的C了,大部分特性都引入了。
什么是C99标准?
2000年3月,ANSI 采纳了 ISO/IEC 9899:1999 标准。这个标准通常指C99。
C99我们最常使用的新特性是:
1、在源代码的中间位置声明变量。
2、用变量为数组长度。
什么是C11标准?
C11标准是C语言标准的第三版(2011年由ISO/IEC发布),前一个标准版本是C99标准。与C99相比,C11有哪些变化呢?
1、 对齐处理:alignof(T)返回T的对齐方式,aligned_alloc()以指定字节和对齐方式分配内存,头文件<stdalign.h>定义了这些内容。
2、 _Noreturn:_Noreturn 是个函数修饰符,位置在函数返回类型的前面,声明函数无返回值,有点类似于gcc的__attribute__((noreturn)),后者在声明语句尾部。
3、 _Generic:_Generic支持轻量级范型编程,可以把一组具有不同类型而却有相同功能的函数抽象为一个接口。
4、 _Static_assert():_Static_assert(),静态断言,在编译时刻进行,断言表达式必须是在编译时期可以计算的表达式,而普通的assert()在运行时刻断言。
5、安全版本的几个函数:gets_s()取代了gets(),原因是后者这个I/O函数的实际缓冲区大小不确定,以至于发生常见的缓冲区溢出攻击,类似的函数还有其它的。
6、 fopen()新模式:fopen()增加了新的创建、打开模式“x”,在文件锁中比较常用。
7、 匿名结构体、联合体。
8、 多线程:头文件<threads.h>定义了创建和管理线程的函数,新的存储类修饰符_Thread_local限定了变量不能在多线程之间共享。
9、 _Atomic类型修饰符和头文件<stdatomic.h>。
10、改进的Unicode支持和头文件<uchar.h>。
11、quick_exit():又一种终止程序的方式,当exit()失败时用以终止程序。
12、复数宏,浮点数宏。
13、time.h新增timespec结构体,时间单位为纳秒,原来的timeval结构体时间单位为毫秒。
什么是C18标准?
C18也称C17是于2018年6月发布的 ISO/IEC 9899:2018 的非正式名称,也是目前(截止到2020年6月)为止最新的 C语言编程标准,被用来替代 C11 标准。
C17 没有引入新的语言特性,只对 C11 进行了补充和修正。
如何查看自己程序的C标准版本?
使用宏__STDC_VERSION__可以输出当前使用的C标准版本,是一个长整型:
printf("C std version:%ld\n", __STDC_VERSION__);
值与标准的对应关系:
标准 | 宏 |
---|---|
C94 | _STDC_VERSION_= 199409L |
C99 | _STDC_VERSION_= 199901L |
C11 | _STDC_VERSION_= 201112L |
C18 | _STDC_VERSION_= 201710L |
如何指定按照某个标准执行编译?
以下的介绍只针对GCC,我没有用过别的编译器。
GCC中可以添加--std=xxx
来指定C标准版本,常用的情况如下:
-std=c11 Conform to the ISO 2011 C standard
-std=c89 Conform to the ISO 1990 C standard
-std=c90 Conform to the ISO 1990 C standard
-std=c99 Conform to the ISO 1999 C stand
-std=gnu11 Conform to the ISO 2011 C standard with GNU extensions
-std=gnu89 Conform to the ISO 1990 C standard with GNU extensions
-std=gnu90 Conform to the ISO 1990 C standard with GNU extensions
-std=gnu99 Conform to the ISO 1999 C standard with GNU extensions
默认情况下,我电脑上的
gcc 5.4.0
使用-std-gnu11