4. 一致性
IMPORTANT
这一章定义了“什么叫符合标准”。如果前面的术语章是词典,这一章就是判定规则:哪些要求必须满足,哪些程序才算严格符合标准,哪些实现才算符合标准。
在本文档中,凡表述为“应”的,表示对实现或程序提出要求;凡表述为“不应”的,表示禁止。
如果某个出现在约束或运行时约束之外的“应”或“不应”要求被违反,则行为为未定义行为。除此之外,本文档也可能通过直接写出“未定义行为”,或者干脆不对行为作显式定义,来表示未定义行为。这三种方式在强调程度上没有差别,表达的都是“此处行为未定义”。
一个程序如果在其他各方面都正确,处理的数据也正确,但包含未指定行为,那么它仍应被视为正确程序,并按照 5.1.2.4 行事。
除非某个
#error预处理指令位于因条件包含而被跳过的组中,否则实现不得成功翻译包含该#error预处理指令的预处理翻译单元。严格符合标准的程序,只能使用本文档规定的语言和库特性。它的输出不得依赖任何未指定行为、未定义行为或实现定义行为,也不得超出任何最小实现限度。
示例:严格符合标准的程序可以使用条件特性(见 6.10.10.4),前提是这种使用被恰当的条件包含预处理指令所保护,并使用了相关宏。例如:
#ifdef __STDC_IEC_60559_BFP__ /* FE_UPWARD defined */
/* ... */
fesetround(FE_UPWARD);
/* ... */
#endif2
3
4
5
符合标准的实现分为两种:宿主实现与独立实现。符合标准的宿主实现,应当接受任何严格符合标准的程序。符合标准的独立实现,应当接受任何严格符合标准的程序,但前提是该程序对库条款(第 7 章)所规定特性的使用,仅限于标准头
<float.h>、<iso646.h>、<limits.h>、<stdalign.h>、<stdarg.h>、<stdbit.h>、<stdbool.h>、<stddef.h>、<stdint.h>和<stdnoreturn.h>的内容。此外,符合标准的独立实现还应当接受任何严格符合标准的程序,只要:
- 使用了头
<string.h>中规定的特性,但下列函数除外:strcoll、strdup、strerror、strndup、strtok、strxfrm;和/或, - 使用了
<stdlib.h>中选定的函数memalignment。
符合标准的实现可以带有扩展(包括额外的库函数),前提是这些扩展不会改变任何严格符合标准程序的行为。1)
- 使用了头
对于定义了
__STDC_IEC_60559_BFP__或__STDC_IEC_60559_DFP__的符合标准的独立实现,其必须接受的严格符合标准程序,还可以使用标准头<fenv.h>、<math.h>的内容,以及标准头<stdlib.h>中的strto*浮点数值转换函数(7.24.1),前提是程序没有把FENV_ACCESSpragma 的状态设为"on"。当
<stdlib.h>在宿主实现中被包含时所有被保留的标识符,在独立实现中包含该头时同样被保留。符合标准的程序,是指能够被符合标准的实现接受的程序。2)
1)这意味着,符合标准的实现除了本文档中明确保留的标识符外,不保留其他标识符。
2)严格符合标准的程序,旨在在各个符合标准的实现之间具有最大的可移植性。符合标准的程序,则可以依赖某个符合标准实现中的不可移植特性。实现应附带一份文档,其中定义所有实现定义特性、区域设置特定特性以及所有扩展。
前向引用:条件包含(6.10.2)、错误指令(6.10.7)、浮点类型的特征 <float.h>(7.7)、替代拼写 <iso646.h>(7.9)、整数类型的大小 <limits.h>(7.10)、对齐 <stdalign.h>(7.15)、可变参数 <stdarg.h>(7.16)、布尔类型和值 <stdbool.h>(7.19)、公共定义 <stddef.h>(7.21)、整数类型 <stdint.h>(7.22)、<stdnoreturn.h>(7.25)。