C语言预定义的宏

凡是遵循 ISO C 标准的编译器都必须定义下面 7 个宏。这些宏的名称都是以两个下划线开始,以两个下划线结束

(1) __DATE__

它的替换文本是一个包含编译日期的字符串字面量,日期格式为"Mmm dd yyyy"(例如:"Mar 192006")。如果天数小于 10,就在日的前面添加一个空格符。

(2) __FILE__

一个含有当前源代码文件名称的字符串字面量。

(3) __LINE__

一个整数常量,其值是当前源文件(包含宏 __LINE__ 引用的文件)的行号,从文件头开始算起。

(4) __TIME__

一个包含编译时间的字符串字面量,格式为"hh:mm:ss"(例如:"08:00:59")。

(5) __STDC__

整数常量 1,表示该编译器遵循 ISO C 标准。

(6) __STDC_HOSTED__

如果当前实现版本是宿主环境下的实现版本,该宏为整数常量 1;否则,为常量 0。

(7) __STDC_VERSION__

如果编译器支持 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 的标准:

(1) __STDC_IEC_559__

如果实现版本的浮点实数算术符合 IEC 60559 标准,则该常量值为 1。

(2) __STDC_IEC_559_COMPLEX__

如果实现版本的浮点复数算术符合 IEC 60559 标准,则该常量值为 1。

(3) __STDC_ISO_10646__

该长整数常量代表 yyyymmL 格式的一个日期(例如:199712L)。如果该常量值被定义,那么类型为 wchar_t 的宽字符编码符合 ISO/IEC 10646 标准,且符合包含到该宏所定义日期为止所制订的所有增补和修订。

C11 标准添加了下面可选的宏:

(1) __STDC_MB_MIGHT_NEQ_WC__

如果一个在基本字符集中的字符,不强制要求它以 wchar_t 对象的编码值等于它对应的字符常量,则该常量值为 1。

(2) __STDC_UTF_16__

如果类型 char16_t 以 UTF-16 方式编码,则该常量值为 1。如果该类型使用其他编码方式,则该宏未定义。

(3) __STDC_UTF_32__

如果类型 char32_t 以 UTF-32 方式编码,则该常量值为 1。如果该类型使用其他编码方式,则该宏未定义。

(4) __STDC_ANALYZABLE__

如果当前实现版本支持 C11 标准中附录 L 中对运行错误的分析,则该常量值为 1。

(5) __STDC_LIB_EXT1__

如果当前实现版本支持 C11 标准中附录 K 中关于边界检查的新函数,则该常量值为 201112L。这些新函数名称均以 _s 结尾。

(6) __STDC_NO_ATOMICS__

如果当前实现版本没有包括针对于原子内存访问操作的类型与函数(不存在头文件 stdatomic.h),则该常量值为 1。

(7) __STDC_NO_COMPLEX__

如果当前实现版本不支持复数算术运算(不存在头文件 complex.h),则该常量值为 1。

(8) __STDC_NO_THREADS__

如果当前实现版本不支持多线程(不存在头文件 threads.h),则该常量值为 1。

(9) __STDC_NO_VLA__

如果当前实现版本不支持可变长度数组,则该常量值为 1。

宏名称 __cplusplus 专为 C++ 编译器保留,因此,当编译 C 源文件时,不可以定义名称为 __cplusplus 的宏。