C语言标准

ISO: International Organization for Standardization,国际化标准组织
IEC: International Electrotechnical Commission,国际电子技术委员会
ANSI: American National Standards Institute,美国国家标准学会。ANSI是ISO中代表美国的成员。
IEEE: Institute of Electrical and Electronics Engineers,电子和电气工程师学会。
POSIX: Portable Operating System Interface,可移植操作系统接口。
SUS: Single UNIX Specification,单一UNIX规范。

ISO C标准

概述

ISO C标准现在由ISO/IEC的C程序设计语言国际标准工作组维护和开发,该工作组称为ISO/IEC JTC1/SC22/WG14,简称WG14,WG14项目官网

ISO C标准的目的是为了保证C程序的可移植性,使其可以运行在大量不同的操作系统(Unix/linux/windows等)

ISO C标准定义了C程序设计语言的语法、语义和标准库(见标准第7章)和相关的约束限制。其只定义了C标准函数库的函数原型、函数功能,而并未定义函数的具体实现。标准库的实现由其他组织实现,如GNU C Library(glibc,当然glibc还包含了除ISO C标准库之外的自己的扩展内容)。

演进历史

  • ANSI X3.159-1989 (C89/ANSI C):1983年ANSI成立了一个X3J11委员会,来创立C语言的标准,因为这个标准在1989年发布,所以也简称C89标准。有些人也把C89成为 ANSI C。
  • ISO/IEC 9899:1990 Programming languages — C (C90):1990年,ISO采纳了ANSI的C89标准,然后做了一些修改再发布,就变成ISO的C90标准了,因此,C89和C90通常指同一个标准。
  • ISO/IEC 9899:1999 Programming languages — C (C99)
  • ISO/IEC 9899:2011 Information technology — Programming languages — C (C11):C11相对于C99的修改,参见标准文档的前言部分,他人总结
  • ISO/IEC 9899:2018 Information technology — Programming languages — C (C17/C18):C17只是解决了针对C11报告的许多缺陷,还包含TC(技术勘误 ISO/IEC 9899:2011/Cor 1:2012),并未引入新的语言功能。

查看和指定使用的C标准(gcc)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
$ cat 002_standard.c  -n
1 #include <stdio.h>
2
3 void main() {
4 printf("C standard: %ld\n", __STDC_VERSION__);
5 }
$ gcc 002_standard.c
$ ./a.out
C standard: 201710
$ gcc --version
gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc -std=c11 002_standard.c
$ ./a.out
C standard: 201112
$ gcc -std=gnu11 002_standard.c
$ ./a.out
C standard: 201112
$ gcc -std=c99 002_standard.c
$ ./a.out
C standard: 199901
$ gcc -std=c89 002_standard.c // __STDC_VERSION__是在 ISO/IEC 9899/AMD1:1995 中才引入的
002_standard.c: In function ‘main’:
002_standard.c:4:33: error: ‘__STDC_VERSION__’ undeclared (first use in this function)
4 | printf("C standard: %ld\n", __STDC_VERSION__);
| ^~~~~~~~~~~~~~~~
002_standard.c:4:33: note: each undeclared identifier is reported only once for each function it appears in

// 查看gcc默认的标准
$ gcc -E -dM - </dev/null |grep -i std|sort
#define __GNUC_STDC_INLINE__ 1
#define __STDC__ 1
#define __STDC_HOSTED__ 1
#define __STDC_IEC_559__ 1
#define __STDC_IEC_559_COMPLEX__ 1
#define __STDC_IEC_60559_BFP__ 201404L
#define __STDC_IEC_60559_COMPLEX__ 201404L
#define __STDC_ISO_10646__ 201706L
#define _STDC_PREDEF_H 1
#define __STDC_UTF_16__ 1
#define __STDC_UTF_32__ 1
#define __STDC_VERSION__ 201710L

$ gcc -std=c11 -E -dM - </dev/null |grep -i std|sort
#define __GNUC_STDC_INLINE__ 1
#define __STDC__ 1
#define __STDC_HOSTED__ 1
#define __STDC_IEC_559__ 1
#define __STDC_IEC_559_COMPLEX__ 1
#define __STDC_IEC_60559_BFP__ 201404L
#define __STDC_IEC_60559_COMPLEX__ 201404L
#define __STDC_ISO_10646__ 201706L
#define _STDC_PREDEF_H 1
#define __STDC_UTF_16__ 1
#define __STDC_UTF_32__ 1
#define __STDC_VERSION__ 201112L

ISO C标准头文件

序号 头文件 C99 C11 备注
1 <assert.h> Y Y 程序断言
2 <complex.h> Y Y 复数运算
3 <ctype.h> Y Y 字符分类(如isalpha)和映射功能(如toupper)
4 <errno.h> Y Y 错误码
5 <fenv.h> Y Y 浮点环境
6 <float.h> Y Y 浮点常量以及特性
7 <inttypes.h> Y Y 包含并扩展了stdint.h
8 <iso646.h> Y Y 逻辑和位操作运算符的宏形式(如and/xor)
9 <limits.h> Y Y 整数类型的极限值(如INT_MAX/INT_MIN)
10 <locale.h> Y Y 本地化相关(如LC_TIME/setlocale())
11 <math.h> Y Y 浮点实数的数学函数、相关宏和类型
12 <setjmp.h> Y Y 非局部性的goto跳转(setjmp()/longjmp())
13 <signal.h> Y Y 信号
14 <stdarg.h> Y Y 可变参数
15 <stdbool.h> Y Y bool类型(bool/true/false宏)
16 <stddef.h> Y Y 类型(ptrdiff_t/size_t/wchar_t)和宏(NULL/offsetof)
17 <stdint.h> Y Y 特定位长的整数类型
18 <stdio.h> Y Y 标准输入输出(I/O)库
19 <stdlib.h> Y Y 实用程序库函数
20 <string.h> Y Y 字符串相关函数
21 <tgmath.h> Y Y 包含math.h和complex.h,并且定义类型特定的宏
22 <time.h> Y Y 时间和日期
23 <wchar.h> Y Y 扩充的多字节和宽字符支持
24 <wctype.h> Y Y 宽字符分类与转换
25 <stdalign.h> N Y 结构体对其相关功能
26 <stdatomic.h> N Y 多线程中公共享数据的原子操作
27 <stdnoreturn.h> N Y 定义宏noreturn
28 <threads.h> N Y 多线程支持
29 <uchar.h> N Y 处理unicode字符

POSIX.1 标准

概述

POSIX是由IEEE制订的标准族。最初POSIX指的只是IEEE标准1003.1-1988(操作系统接口),后来则扩展成包括很多标记为1003的标准及标准草案,如shell和实用程序(1003.2)。其正式称呼为 IEEE 1003,而国际标准名称为 ISO/IEC 9945。

这些标准涵盖了很多方面,比如Unix系统调用的C语言接口、shell程序和工具、线程及网络编程。

这些标准的制定目的是为了提升应用程序在不同UNIX系统环境之间的可移植性。他是ISO C的超集。同样的,POSIX也只是定义接口,而不定义具体的实现。

POSIX标准族中的1003.1也被称为POSIX.1标准。

POSIX.2标准(ISO/IEC 9945-2:1993)主要是对shell和包括C编译器命令行接口在内的各种Unix工具进行了标准化。

演进

X/Open 公司是由多家国际计算机厂商所组成的联盟,他们的目的是为了制定出一套全面而又一致的开放系统标准。1993年,该公司获得Unix的商标权。

OSF: Open System Software Foundation,开放系统软件基金会。OSF是20世纪80年代末UNIX纷争期间成立的两家厂商联盟之一。OSF的主要成员包括 Digital、 IBM、 HP、 Apollo、 Bull、 Nixdorf 和 Siemens。 OSF 成立的主要目的是为了应对由 AT&T( UNIX 的发明者)和 SUN 公司( UNIX 工作站市场的领跑者)结盟所带来的威胁。

1996年,X/Open和OSF合并成立 The Open Group。

1999年,出于修订并加强POSIX标准和SUS规范的目的,IEEE、Open Group以及 ISO/IEC联合技术委员会共同成立了austin公共标准修订工作组(Common Standards Revision Group, CSRG),现在POSIX标准仍由austin Group维护。

POSIX.1

  • IEEE std 1003.1-1988: POSIX.1的第一个版本
  • ISO/IEC 9945-1:1990|IEEE std 1003.1-1990: 1990年 IEEE std 1003.1-1988被采纳为ISO标准
  • IEEE std 1003.1-1996|ISO/IEC 9945-1:1996: 包含内容见下面列表
    • IEEE std 1003.1-1990
    • IEEE std 1003.1b-1993(对基本POSIX标准的实时性扩展)
    • IEEE std 1003.1c-1995(pthreads)
    • IEEE std 1003.1i-1995(实时技术勘误表)
  • IEEE std 1003.1-2001: 包含的内容很多,见下面列表
    • IEEE std 1003.1-1996
    • IEEE P1003.1a草案(系统接口修正)
    • IEEE std 1003.1d-1999(高级实时扩展)
    • IEEE std 1003.1j-2000(更多高级实时扩展)
    • IEEE std 1003.1q-2000(事件跟踪方面的扩展)
    • 部分IEEE std 1003.1g-2000(协议无关接口)
    • ISO/IEC 9945-2:1993:即IEEE std 1003.2-1993(POSIX.2)
    • IEEE P1003.2b草案(shell及实用程序的修正)
    • IEEE std 1003.2d-1994(批处理扩展)
    • SUSv2:包括系统接口定义(第五版)、命令和实用程序(第五版)、系统接口和头文件(第五版)
    • Open Group 技术标准,网络服务,5.2发行版
    • ISO/IEC 9899:1999(C99)
  • IEEE std 1003.1-2008|ISO/ICE 9945:2009:该标准基于下面几个标准
    • IEEE std 1003.1-2004
    • Open Group技术标准,2006,扩展API集,第1~4部分
    • ISO/IEC 9899:1999

XPG & SUS

X/Open公司编纂的 《X/Open Portability Guide》(XPG,X/Open 可移植性指南)是一套基于POSIX 标准的可移植性指导丛书。XPG是X/Open公司的出版物

SUS是Open Group公司的出版物。
SUS 是POSIX.1标准的一个超集,POSIX.1相当于SUS中的基础规范部分。
XSI: X/Open System Interface, X/Open系统接口。
POSIX.1中的XSI选项描述了可选的接口,也定义了遵循XSI的实现必须支持POSIX.1的哪些可选部分。只有遵循XSI的实现才能称为UNIX系统。

  • XPG3: X/Open于1989年发布首个重要版本,是基于IEEE std 1003.1:1988。
  • XPG4:X/Open于1992年发布,基于IEEE std 1003.1:1990 和 IEEE std 1003.2:1992
  • XPG4v2|SUSv1|UNIX95: X/Open于1994年发布,因为它大约包含了1170个接口,因此也被称为 “Spec 1170”,主要内容包括:
    • X/Open 通用应用环境(Common Application Environment, CAE)第四发行版(前身就是XPG4)
    • System V接口定义(System V Interface Definition,SVID)第三版Level 1接口
    • OSF应用环境规范(Application Environment Specification, AES)Full Use接口
  • SUSv2|UNIX98: Open Group于1997年发布
  • SUSv3: Open Group于2001年发布,基本规范与IEEE std 1003.1-2001相同,除此之外还包括X/Open Curses第4发行版第2版。SUSv3 规范可在线获得,网址是 http://www.unix.org/version3/online.html。通过 SUSv3 认证的 UNIX 实现可被称为 UNIX 03。它的基本规范约有3700页,包含以下4个部分:
    • 基本定义(XBD),包含了定义、术语、概念以及对头文件内容的规范。总计提供了84个头文件的规范。
    • 系统接口(XSH),首先介绍了各种有用的背景信息。主要内容包含对各种函数(在特定的 UNIX 实现中,这些函数要么是作为系统调用,要么是作为库函数来实现的)的定义。总计包括了 1123 个系统接口。
    • Shell 和实用工具(XCU),明确定义了 shell 和各种 UNIX 命令的行为。总共定义了160 个实用工具的行为。
    • 基本原理(XRAT),包括了与前三部分有关的描述性文字和原理说明
  • SUSv4:Open Group与2008年发布,较之于之先前版本,该标准包含了基本规范以及 XSI 扩展。

SUS(和XPG)标准顺应了相应的POSIX标准,并被组织为POSIX的超集。除了对许多额外的接口作出规范外,SUS标准还将很多被POSIX视为可选的接口和行为规范作为了必选项。

POSIX.1-2001定义了两种规范符合度:

  • POSIX规范符合度
  • XSI规范符合度。对 UNIX 实现来说,要想完全符合 XSI 规范,除了必须满足 POSIX 规范的所有规定之外,还要提供若干POSIX 规范中的可选接口和行为。只有这一规范符合度达标,才能从 OPEN GROUP获得 UNIX03 称号

各种标准之间的关系

实线表示标准间的直接过渡,虚线则表示标准间有一定的瓜葛,这无非有两种情况:其一,一个标准被并入了另一标准;其二,一个标准依附于另一个标准。

各种标准之间的关系

查看使用的POSIX.1标准

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ getconf _POSIX_VERSION
200809
$ ldd --version |grep -i ldd
ldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35
$ gcc --version |grep -i gcc
gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0
$ cat 002_standard.c
#include <stdio.h>
#include <unistd.h>

void main() {
printf("posix standard: %ld\n", _POSIX_VERSION);
}
$ gcc 002_standard.c
$ ./a.out
posix standard: 200809
$

POSIX.1-2008 标准头文件

序号 头文件 必选 备注
1 <aio.h> 异步输入和输出
2 <arpa/inet.h> 互联网相关处理定义
3 <cpio.h> cpio archive format宏定义
4 <dirent.h> format of directory entries
5 <dlfcn.h> 动态链接处理
6 <fcntl.h> 文件控制
7 <fmtmsg.h> 消息显示格式
8 <fnmatch.h> 文件名匹配类型
9 <ftw.h> 文件树遍历
10 <glob.h> pathname pattern-matching types
11 <grp.h> group structure
12 <iconv.h> 代码集转换
13 <langinfo.h> 语言信息常量
14 <libgen.h> 路径模式匹配(dirname/basename)
15 <monetary.h> 货币类型与函数
16 <mqueue.h> 消息队列
17 <ndbm.h> 数据库操作
18 <net/if.h> sockets local interfaces
19 <netdb.h> 网络数据库操作
20 <netinet/in.h> internet address family
21 <netinet/tcp.h> tcp协议定义
22 <nl_types.h> 消息类型
23 <poll.h> poll
24 <pthread.h> 多线程
25 <pwd.h> 口令文件
26 <regex.h> 正则表达式
27 <sched.h> 执行调度
28 <search.h> search tables
29 <semaphore.h> 信号量
30 <spawn.h> spawn (ADVANCED REALTIME)
31 <strings.h> 字符串操作
32 <stropts.h>
33 <sys/ipc.h> XSI 进程间通信
34 <sys/mman.h> 内存管理
35 <sys/msg.h> XSI 消息队列
36 <sys/resource.h> XSI 资源操作
37 <sys/select.h>
38 <sys/sem.h> XSI 信号量
39 <sys/shm.h> XSI 共享内存
40 <sys/socket.h> 套接字接口
41 <sys/stat.h> 文件属性
42 <sys/statvfs.h> vfs文件系统信息
43 <sys/time.h>
44 <sys/times.h>
45 <sys/types.h>
46 <sys/uio.h> vector I/O操作
47 <sys/un.h>
48 <sys/utsname.h>
49 <sys/wait.h>
50 <syslog.h>
51 <tar.h>
52 <termios.h>
53 <trace.h>
54 <ulimit.h>
55 <unistd.h>
56 <utime.h>
57 <utmpx.h>
58 <wordexp.h> 字扩展类型