題:
誰收到main()返回的值?
user18118
2013-01-22 22:25:05 UTC
view on stackexchange narkive permalink

我知道在計算機中, main()函數返回的值被操作系統接收。但是,在 main()函數中微控制器?

當我將C用於PIC微控制器時,我總是使用void main()。當將C編譯器用於微控制器時,這根本沒有關係。因為沒有運行(例如)“ main.c”的操作系統。如果該微控制器中運行著類似RTOS的操作系統,則操作系統為“ main.c”。
並不是真正的重複,但至少與之相關:http://electronics.stackexchange.com/q/30830/4950
通常如何決定啟動功能的定義。您使用的環境將記錄受支持的啟動功能表單。託管的C實現必須支持具有兩種不同簽名的兩種形式的“ main”形式,兩者均返回“ int”形式。如果您使用的是獨立的C實現,則該實現將指示您應如何編寫啟動函數。你不能僅僅因為不返回就編寫一個`void`返回函數。不返回的*行為*與影響整個調用約定的函數* type *不同。
五 答案:
Dave Tweed
2013-01-22 22:50:27 UTC
view on stackexchange narkive permalink

在微控制器上,實際上並不會期望 main()退出,並且如果行為未定義,則取決於為微控制器編寫C運行時的人。我看到過這樣的系統:

  • main()周圍有一個隱式循環,因此,如果退出,則只需再次調用它即可。
  • 具有一個簡單的“跳轉到自身”循環(或HALT指令),如果 main()退出,則會執行該循環。
  • 只需執行其餘代碼存儲器在調用 main()之後。這被稱為“逃入野草”。

我從未見過有人真正對 main()返回的值進行任何操作。如果這是您真正關心的事情,那麼您應該查看並可能修改系統C運行時庫的源代碼。

你擊敗了我。 +1表示同步。
定義“ main()”具有“ int”返回值的C標準顯然不是在設計時考慮了無操作系統的微控制器。因此,這是未指定的行為,並且可能會發生任何事情,具體取決於您的C運行時,如Dave所列。
在無操作系統的微控制器上運行的C被認為是獨立的實現,並且C標準甚至不需要獨立的環境來擁有main(),更不用說定義其返回值了。這取決於實現者。
@ndim-要拆分頭髮,`void main(void)`是*實現定義的行為*,不是*未指定的行為*
@MichaelEdenfield:確實如此。但是,C中的“所有”代碼都是根據功能定義的,因此,永遠不可能完全用C編寫一個完全完整的系統。至少需要使用一小部分的彙編語言(或其他任何一種語言)來設置最小的環境,以便可以調用C函數。該函數最明顯的名稱是`main()`。
@ndim C標準指出,任何形式的main都可以。您閱讀標準了嗎?更重要的是,您是否檢查了指定“ main”的“ int”格式的部分位於哪個子章節?5.1.2.2託管環境。
至少* my *啟動代碼將繼續調用全局析構函數,因此寫入stdout的所有內容仍將被刷新。
為了解釋上面的@Lundin's註釋:C標準知道一個“託管環境”(即程序在適當的OS上正確運行),其中main(...)應該*返回一個int。然後是“獨立環境”(即基本上在裸機上運行的程序),其中“在啟動時調用的函數的名稱和類型是實現定義的”。因此,任何事情在您的微控制器環境中都會發生,並且您最好查看一下源代碼生成的二進製文件中包含的啟動代碼實際上對反彙編程序的作用。
@ndim即使在託管的實現中(首先與大多數EE問題都不相關),也可以以實現定義的形式聲明main。這個標準還不清楚。[這裡的詳細信息](http://stackoverflow.com/a/31263079/584518)
如果您返回的內容凍結,我在跳轉到main之後也遇到了HALT指令。
@istepaniuk:相當於我的第二個項目符號。並非所有的微控制器都有HALT指令。
Lundin
2016-06-20 11:46:30 UTC
view on stackexchange narkive permalink

一個常見的誤解/誤解是 int main 是標準指定的唯一有效形式。那是不對的。

C標準涉及兩種實現:託管和獨立。在這種情況下,“實施”是指編譯器。託管編譯器針對特定的OS進行編譯,而獨立編譯器針對特定的裸機應用進行編譯。嵌入式系統幾乎總是獨立的系統-即使是RTOS。

獨立的實現可以對 main()使用任何形式,甚至不需要一個名為main的函數。大多數情況下,它們使用 void main(void)的形式,因為返回任何內容都沒有意義。

在這裡要意識到的重要一點是,始終由編譯器決定 main()的形式,而不是由程序員決定。

要做 main()返回某些內容的獨立實現非常有問題。讓您想知道編寫編譯器的人是否真的閱讀了標準...

詳細信息

Andrew
2013-01-23 03:40:45 UTC
view on stackexchange narkive permalink

C語言標准允許實現定義的變體 void main(void),這是嵌入式系統中的常見形式-只是因為預期它們不會返回。

如果您查看編譯器的設置,通常會有一個自舉代碼段,從復位向量中調用,它會在調用main()之前執行一些基本的初始化操作(包括將初始化值複製到變量中)。 p>如果 main()返回

,這通常也會處於無限循環內,或者可能會執行重置
kwesolowski
2014-08-09 02:47:45 UTC
view on stackexchange narkive permalink

它(如其他答案所述)取決於您的工具鏈,但是例如在GCC中, main 被編譯為其他函數,因此其返回值將根據調用約定進行存儲(在ARM上,

我猜這在AVR-GCC上是類似的,因此自定義腳本可以在主返回之後使用該值。

這有點錯了
它強調,調用“ main”的人可以獲得其返回值。當然,在99.9%的情況下它將被忽略,但是答案提供了可以接收此返回值的信息。
old_timer
2020-04-04 22:18:16 UTC
view on stackexchange narkive permalink

您不能在沒有引導程序的情況下進入C引導程序代碼,理想情況下,該代碼是用asm編寫的(如果在C語言中您遇到了雞和雞蛋的問題),則準備了運行C的環境來設置堆棧,preps .data,preps .bss ,然後調用main。有些人認為主線永遠不會回來,但是裸機的美麗在於一切。您當然可以在單片機中從main返回,例如,當發生致命事件時,或者如果您的設計是100%事件(中斷)驅動的,則設置所有外設和中斷,然後返回並讓自舉旋轉成無限循環,即比一段時間還漂亮(1)繼續;在main()代碼中。

許多人使用罐頭庫和環境來使裸機感覺不像裸機,而對下面發生的事情負責,卻不想看或控制它。再次成為裸機之美的一部分。

當主要收益取決於系統(無論是操作系統還是MCU上的裸機)時會發生什麼。明智的設計應允許main返回引導程序,然後根據該設計選擇要執行的操作,至少要進入無限循環。

main()在大多數情況下只是編譯器的另一個函數名稱,某些工具鏈在看到該函數時會添加一些額外的內容,因此您應在裸機環境中謹慎使用該函數,以避免在這種資源受限的環境中產生過多的負擔。使用名稱main()以外的C入口點來避免該問題不是不明智的做法,但是自然地,這通常涉及對整個事物進行控制,而不是僅向其他人的沙箱添加幾行(編寫您自己的引導程序和可能的鏈接器)腳本,因此也可能是庫(這不是一個壞主意)。

一旦接管您,您肯定可以從main那裡得到返回值,在中斷驅動設計的情況下,main()可以簡單地啟動運動,然後返回無限或等待中斷循環。引導程序,但您可以選擇讓返回值導致採取行動(如果不為零),然後進行時鐘門控或將所有外設置於復位狀態以實現低功耗啟動失敗。

簡短的回答:返回值進入以太坊,因為通常您直接進入無限循環,或者在引導程序假設發生了某些不良情況並關閉或取消完成您在應用程序部分中配置的任何內容後,就進入無限循環。任何不允許main()返回的沙箱都是避免使用的沙箱,它至少應具有最小的支持(無限循環)。

更短的答案:誰收到返回值?您應對此應用負責,因此需要執行引導程序。



該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...