凡是遵循 ISO C 标准的编译器都必须定义下面 7 个宏。这些宏的名称都是以两个下划线开始,以两个下划线结束:
它的替换文本是一个包含编译日期的字符串字面量,日期格式为"Mmm dd yyyy"(例如:"Mar 192006")。如果天数小于 10,就在日的前面添加一个空格符。
一个含有当前源代码文件名称的字符串字面量。
一个整数常量,其值是当前源文件(包含宏 __LINE__ 引用的文件)的行号,从文件头开始算起。
一个包含编译时间的字符串字面量,格式为"hh:mm:ss"(例如:"08:00:59")。
整数常量 1,表示该编译器遵循 ISO C 标准。
如果当前实现版本是宿主环境下的实现版本,该宏为整数常量 1;否则,为常量 0。
如果编译器支持 1999 年 1 月的 C99 标准,则该宏为长整数常量 199901L。如果编译器支持 2011 年 12 月的 C11 标准,则该宏为长整数常量 201112L。
#line 命令可影响 __FILE__ 和 __LINE__ 宏的值。其他预定义的宏则完全不受任何外部因素影响,在整个编译过程中都是常量。
常量 __STDC_VERSION__ 的值在未来新的 C 语言国际标准中会被调整。
从 C99 标准开始,C 程序或者在宿主环境(hosted)中执行,或者在独立环境(freestanding)中执行。大多数 C 程序都在宿主环境中执行,也就是说,C 程序在操作系统的控制和支持之下执行。在这种情况下,常量 __STDC_HOSTED__ 的值是 1,且拥有完整的标准库。
如果程序在独立环境中执行,则没有操作系统的支持,因此只需要最少的标准库资源就可以使用。
与前面列举的宏不同,下面的标准宏只有在特定的条件下才会被预定义。如果下面这些宏中有任何一个被定义,表示该实现版本支持某个 IEC 或 ISO 的标准:
如果实现版本的浮点实数算术符合 IEC 60559 标准,则该常量值为 1。
如果实现版本的浮点复数算术符合 IEC 60559 标准,则该常量值为 1。
该长整数常量代表 yyyymmL 格式的一个日期(例如:199712L)。如果该常量值被定义,那么类型为 wchar_t 的宽字符编码符合 ISO/IEC 10646 标准,且符合包含到该宏所定义日期为止所制订的所有增补和修订。
C11 标准添加了下面可选的宏:
如果一个在基本字符集中的字符,不强制要求它以 wchar_t 对象的编码值等于它对应的字符常量,则该常量值为 1。
如果类型 char16_t 以 UTF-16 方式编码,则该常量值为 1。如果该类型使用其他编码方式,则该宏未定义。
如果类型 char32_t 以 UTF-32 方式编码,则该常量值为 1。如果该类型使用其他编码方式,则该宏未定义。
如果当前实现版本支持 C11 标准中附录 L 中对运行错误的分析,则该常量值为 1。
如果当前实现版本支持 C11 标准中附录 K 中关于边界检查的新函数,则该常量值为 201112L。这些新函数名称均以 _s 结尾。
如果当前实现版本没有包括针对于原子内存访问操作的类型与函数(不存在头文件 stdatomic.h),则该常量值为 1。
如果当前实现版本不支持复数算术运算(不存在头文件 complex.h),则该常量值为 1。
如果当前实现版本不支持多线程(不存在头文件 threads.h),则该常量值为 1。
如果当前实现版本不支持可变长度数组,则该常量值为 1。
宏名称 __cplusplus 专为 C++ 编译器保留,因此,当编译 C 源文件时,不可以定义名称为 __cplusplus 的宏。