谁收到main()返回的值?


34

我知道在计算机中,该main()函数返回的值由操作系统接收。但是,main()微控制器的功能会发生什么?


7
当我将C用于PIC微控制器时,我总是使用void main()。当将C编译器用于微控制器时,这根本没有关系。因为没有运行(例如)“ main.c”的操作系统。如果在该微控制器中运行类似RTOS的操作系统,则操作系统为“ main.c”。
Abdullah kahraman

4
不是真正的重复,但至少是相关的:electronics.stackexchange.com/q/30830/4950
PetPaulsen

1
通常如何决定启动功能的定义。您使用的环境将记录受支持的启动功能表单。托管的C实现需要支持main具有两种不同签名的两种形式,两者都返回int。如果您使用的是独立的C实现,则该实现将指示您应如何编写启动函数。您不能void仅仅因为不返回就编写返回函数。不返回的行为不同于影响总体调用约定的函数类型
卡兹(Kaz)2013年

Answers:


42

在微控制器上,main()实际上并没有预期会退出,如果没有定义,则行为也没有定义-因此,由谁为微控制器编写C运行时决定。我见过以下系统:

  • 周围有一个隐式循环main(),因此,如果退出,则只需再次调用它即可。
  • 有一个简单的“跳至自身”循环,一旦main()退出就会执行。
  • 只需执行对调用之后的其余代码存储main()。这称为“逃入杂草”。

我从未见过使用所返回的值实际执行任何操作的人main()。如果这是您真正关心的事情,那么您应该查看并可能修改系统C运行时库的源代码。


1
你击败了我。+1表示同步。
亚当·劳伦斯

9
定义main()具有int返回值的C标准显然不是在设计无OS微控制器的情况下设计的。因此,这是未指定的行为,并且可能会发生任何事情,具体取决于您的C运行时,如Dave所列。
ndim

4
在无操作系统的微控制器上运行的C可以被认为是独立的实现,而C标准甚至不需要独立的环境就可以拥有一个main(),更不用说定义其返回值了。这取决于实现者。
KutuluMike

2
@ndim-分裂头发,void main( void )实现定义的行为,而不是未指定的行为
安德鲁

1
@MichaelEdenfield:的确如此。但是,C语言中的所有代码都是根据功能定义的,因此,永远不可能有完全用C语言编写的原始系统。至少需要使用一小部分的汇编语言(或其他任何一种语言)来设置最小的环境,以便可以调用C函数。该函数最明显的名称是main()
戴夫·特威德

5

常见的误解/误解是int main该标准指定的唯一有效形式。那是不对的。

C标准涉及两种实现:托管和独立。在这种情况下,“实施”是指编译器。托管编译器针对特定的OS进行编译,而独立编译器针对特定的裸机应用进行编译。嵌入式系统几乎总是独立的系统-即使是RTOS。

独立的实现可以使用任何形式main(),它们甚至不需要具有称为main的功能。大多数情况下,他们使用这种形式void main (void),因为返回任何东西都没有意义。

在这里要意识到的重要一点是,始终由编译器来决定格式,main()而不是由程序员来决定。

确实从中返回某些东西的独立实现main()是非常可疑的。让您想知道编写编译器的人员是否真的阅读了标准...

详细信息在这里


3

C语言标准允许实现定义的变体void main( void ),这是嵌入式系统中的常见形式-只是因为不希望它们返回。

如果您看一下编译器的设置,通常会有一个自举代码段,从复位向量中调用,它会在调用main()之前执行一些基本的初始化操作(包括将初始化值复制到变量中)。

这通常也会在无限循环内,或者如果main()返回则执行重置


0

它(如提到的其他答案)取决于您的工具链,但是例如在GCC main中将其编译为其他函数,因此其返回值将根据调用约定进行存储(在ARM上我不正确使用GCC,它将被放到R0中)在返回之前)。

我猜这在AVR-GCC上是类似的,因此自定义脚本可以在主返回后使用此值。


这颇有失误
克里斯·斯特拉顿

它强调调用者main可以获取其返回值。当然,在99.9%的情况下它会被忽略,但是答案提供了可以接收此返回值的信息。
kwesolowski
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.