我阅读了关于GCC的this官方手册。有时我翻译文本有问题。在第6页(第2.1章)我无法理解这样的文本片段:
ISO C标准(在第4节中)定义了两类符合性 实现。符合标准的托管实现支持整体 标准包括所有图书馆设施;一致的 独立实施只需要提供一定的 图书馆设施:
<float.h>
,<limits.h>
,<stdarg.h>
和。<stddef.h>
<iso646.h>
;自AMD1以来,<stdbool.h>
;既然是C99,也是<stdint.h>
和<stdalign.h>
中的人;从C11开始,也是那些int main (void)
和。此外,复杂的类型,添加 独立实施不需要C99。标准 还为程序定义了两个环境,一个独立的 环境,所有实施所需的,可能没有的 图书馆设施超出独立所需的范围 实现,程序启动和终止的处理 是实现定义的,是托管环境,而不是 必需的,其中提供了所有图书馆设施并启动 是通过函数int main (int, char *[])
或main
。一个 操作系统内核将是一个独立的环境;一个程序使用 操作系统的设施通常是托管的 实施
我不确定我是否理解......
我将重新阐述我的理解:
轻型版本适用于OS开发。完整版本适用于程序,可在OS中使用。
我不理解关于{{1}}函数的短语。
我要求向我解释这段文字。
答案 0 :(得分:7)
这两者都有。
该标准定义了两个运行时环境。一个人拥有所有语言,加上标准运行时库的一小部分,以及其他实现定义的东西。这是独立环境,并且(正如您猜测的那样)是用于裸机编程的,例如,操作系统内核。
另一个更复杂的环境包括上述所有功能以及所有标准运行时库。这是一个托管环境,用于应用程序编程。
现在,实现只是必需才能包含独立环境的功能。如果这就是全部,那就称为独立实现。深度嵌入式微控制器的交叉编译器通常是独立的实现,因为大部分标准C运行时没有意义或者太大而不适合。
实施托管环境是可选的;如果实现提供托管环境,则称为托管实现。托管实现必须还提供独立环境,即只有独立实现的设施可用的编译模式。 (这种模式通常用于编译C运行时本身,其中大部分只是C语言。)
最后,main
(int main(void)
和int main(int, char **)
)的标准签名是托管环境的一部分。独立环境也可以使用这些签名,但它也可以将main
的签名定义为它喜欢的任何内容(void main(void)
是常见的)或使用不同的名称作为入口点。
答案 1 :(得分:3)
C11 4/6:
这两种符合规范的实施方式是托管和独立的。符合要求的托管实现应接受任何严格符合的程序。符合标准的独立实施应接受任何严格符合的程序,其中使用库条款(第7节)中规定的特征仅限于标准标题
<float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, and <stdnoreturn.h>
的内容。
首先请注意,在C标准的上下文中,“实现”意味着“C编译器的实现”而不是其他内容。
正如您在问题中正确陈述的那样,独立实现是一个系统的编译器,它不打算在其下面有一个操作系统。换句话说,独立式实现编译器生成的程序既可以是在“裸骨”CPU上运行的嵌入式应用程序,也可以是作为操作系统的程序。托管实现是一种编译器,适用于在操作系统之上运行的应用程序。
独立应用程序的编译器只需提供上述标题。其余的标题(例如stdio.h)在标准的“第7条”中定义,但它们对于独立实现不是强制性的。
但是请注意,对于托管或独立实现,几个库都不是必需的,例如复数库: C11 7.3.1:
“定义宏的实现_ _STDC_NO_COMPLEX_ _不需要 提供此标题也不支持其任何设施。“
此外,两个不同的执行环境(独立和托管)允许main()的语法不同,可以找到更多信息here。程序员之间非常普遍的误解是,C中唯一允许的表单是int main()
,这在托管环境中才是真实的。
例如,独立程序可以从复位后中断服务程序开始。从那里它可以调用void main()
函数,或者它可以完全调用其他函数:它是实现定义的。
答案 2 :(得分:1)
这意味着在启动时执行main()函数不需要独立环境。例如,它可能正在寻找_main()(确切的名称和签名是实现定义的)。