译自ISO/IEC 9899:2018(即C17标准)
4. 一致性(节选)
两种形式的一致性实现是托管(hosted)的和独立(freestanding)的。符合要求的托管实现应接受任何严格符合要求的程序。符合标准的独立实现应接受任何严格符合标准的程序,其中库条款(第 7 条)中指定的功能的使用仅限于标准头文件<float.h>、<iso646.h>、<limits.h>、<stdalign.h>、<stdarg.h>、<stdbool.h>、<stddef.h>、<stdint.h>和<stdnoreturn.h>。一个符合要求的实现可能有扩展(包括额外的库函数),只要它们不改变任何严格符合的程序的行为。
5.1.2 执行环境
定义了两种执行环境:独立(freestanding)和托管(hosted)。在这两种情况下,程序启动都是在执行环境调用指定的 C 函数时发生的。所有具有静态存储持续时间的对象都应在程序启动之前进行初始化(设置为其初始值)。这种初始化的方式和时间是未指定的。程序终止将控制权返回给执行环境。
5.1.2.1 独立环境
在独立环境中(C 程序的执行可能在没有操作系统的任何好处的情况下发生),程序启动时调用的函数的名称和类型是实现定义的。除了第 4 条要求的最小集合(即float.h,iso646.h,limits.h,stdalign.h,stdarg.h,stdbool.h,stddef.h,stdint.h和stdnoreturn.h)之外,独立程序可用的任何库设施都是实现定义的。
独立环境中程序终止的效果是实现定义的。
5.1.2.2 托管环境
无需提供托管环境,但应符合以下规范(如果存在)。
5.1.2.2.1 程序启动
程序启动时调用的函数名为 main。实现没有声明这个函数的原型。它应定义为返回类型为 int 且不带参数:
int main(void) { /* ... */ }
或者带有两个参数(这里称为 argc 和 argv,尽管可以使用任何名称,因为它们是声明它们的函数的局部变量):
int main(int argc, char *argv[]) { /* ... */ }
或其等价形式; 或以其他一些实现定义的方式。
如果它们被声明,main
函数的参数应遵守以下约束:
-
argc
的值应为非负数。 -
argv[argc]
应该是一个空指针。 - 如果
argc
的值大于零,则数组成员argv[0]
到argv[argc-1]
应包含指向字符串的指针,这些指针在程序启动之前由托管环境给出实现定义的值。目的是从托管环境中的其他地方向程序提供在程序启动之前确定的信息。如果托管环境不能提供大写和小写字母的字符串,则实现应确保以小写形式接收字符串。 - 如果
argc
的值大于零,则argv[0]
指向的字符串代表程序名;如果程序名称在托管环境中不可用,则argv[0][0]
应为空字符。 如果argc
的值大于 1,则argv[1]
到argv[argc-1]
所指向的字符串代表程序参数。 - 参数
argc
和argv
以及argv
数组指向的字符串应该可以被程序修改,并在程序启动和程序终止之间保留它们最后存储的值
5.1.2.2.2 程序执行
在托管环境中,程序可以使用库章节(第 7 章)中描述的所有函数、宏、类型定义和对象。
5.1.2.2.3 程序终止
如果main
函数的返回类型是与 int 兼容的类型,则从初始调用到main
函数的 return 等价于以main
函数返回的值作为参数调用exit
函数;到达终止main
函数的 } 返回值 0。如果返回类型与 int 不兼容,则返回给宿主环境的终止状态未指定。
5.1.2.4 多线程执行和数据竞争
在托管实现下,一个程序可以同时运行多个执行线程(或线程)。每个线程的执行按照本文档其余部分的定义进行。整个程序的执行包括其所有线程的执行。在独立实现下,程序是否可以有多个执行线程是由实现定义的。