main()によって返される値を受け取るのは誰ですか?


34

コンピューターでmain()は、関数によって返された値がオペレーティングシステムによって受信されることを知っています。しかし、main()マイクロコントローラーの機能はどうなりますか?


7
PICマイクロコントローラーにCを使用しているときは、常にvoid main()を使用します。マイクロコントローラー用のCコンパイラーを使用する場合、それはまったく問題ではありません。(たとえば) "main.c"を実行するオペレーティングシステムがないためです。そのマイクロコントローラで実行されているRTOSのようなものがある場合、オペレーティングシステムは「main.c」です。
アブドラカーラマン

4
ない本当に重複しますが、関連する少なくとも:electronics.stackexchange.com/q/30830/4950
PetPaulsen

1
通常、スタートアップ関数の定義方法はユーザーが決めることはできません。使用している環境は、サポートされているスタートアップ関数フォームを文書化します。ホストされたC実装はmain、2つの異なるシグネチャを持つ2 つの形式をサポートする必要があり、どちらもreturn intです。自立型のC実装を使用している場合、その実装により、スタートアップ関数の記述方法が決まります。void返さないという理由だけで、返される関数を書くことはできません。戻らないという動作は、全体的な呼び出し規約に影響を与える関数タイプとは異なります。
カズ

回答:


42

マイクロコントローラー上でmain()は、実際に終了することは期待されておらず、その場合の動作は定義されていません。したがって、マイクロコントローラー用のCランタイムを作成したユーザー次第です。次のようなシステムを見てきました。

  • の周りmain()に暗黙のループがあるので、終了した場合、単純に再び呼び出されます。
  • main()終了すると実行される単純な「自己ジャンプ」ループを使用します。
  • の呼び出しに続く残りのコードメモリを実行するだけmain()です。これは「雑草に飛び込む」と呼ばれます。

によって返された値で実際に何かをするものを見たことはありませんmain()。これが実際に気になるものである場合は、システムのCランタイムライブラリのソースコードを確認し、場合によっては変更する必要があります。


1
あなたは私を打ち負かした。シンクロニシティの場合は+1。
アダムローレンス

9
戻り値main()を持つことを定義しているC標準は、int明らかにOSなしのマイクロコントローラーを念頭に置いて設計されていません。したがって、これは不特定の動作であり、Daveがリストしたように、Cランタイムに応じて何かが発生する可能性があります。
ndim

4
OSなしのマイクロコントローラーで実行されるCは、独立した実装と見なすことができます。C標準では、戻り値を定義するためのを持っている独立した環境さえも必要としませんmain()。それは実装者次第です。
KutuluMike

2
@ndim-ヘアを分割することvoid main( void )は、実装定義の動作であり、不特定の動作ではありません。
アンドリュー

1
@MichaelEdenfield:確かに。ただし、Cのすべてのコードは関数の観点から定義されているため、Cで完全に記述されたフレスティングシステムを持つことは決してできません。C関数を呼び出すことができるように、最小限の環境をセットアップするアセンブリ言語(または何でも)が少なくとも必要です。その関数の最もわかりやすい名前はmain()です。
デイブツイード

5

一般的な誤解/神話はint main、標準で指定されている唯一の有効な形式です。それは真実ではありません。

C標準では、ホスト型と自立型の2つの実装について説明しています。この場合の「実装」とは、コンパイラを意味します。ホストされたコンパイラは特定のOS向けにコンパイルされ、自立型コンパイラは特定のベアメタルアプリケーション向けにコンパイルされます。組み込みシステムは、ほとんどの場合、RTOSの場合でも独立したシステムです。

独立型の実装では、に任意の形式を使用できますmain()が、mainと呼ばれる関数さえ必要ありません。ほとんどの場合、フォームを使用しvoid main (void)ます。何も返さないのは意味がないからです。

ここで重要なことは、プログラマーのフォームを決定するのはコンパイラーmain()あり、プログラマーではないことです。

自立型の実装を行うからの戻り何かがmain()非常に疑問です。コンパイラを作った人が実際に標準を読んでいるかどうか疑問に思います...

詳細はこちら


3

C言語標準では、実装で定義されたバリエーションが許可されてvoid main( void )おり、これは組み込みシステムの通常の形式です。

コンパイラのセットアップを見ると、通常、リセットベクトルから呼び出されるコードのブートストラップスニペットがあり、main()を呼び出す前に基本的な初期化(変数への初期化値のコピーなど)を実行します。

これは、(通常)無限ループ内にあるか、main()リターンする場合はおそらくリセットを実行します


0

(他の回答で述べたように)ツールチェーンに依存しますが、たとえばGCC mainでは他の関数としてコンパイルされるので、その戻り値は呼び出し規約に従って保存されます(ARMではGCCではなくR0に使用されます帰国直前)。

これはAVR-GCCでも似ているため、カスタムスクリプトはメインのリターン後にこの値を使用できます。


これはむしろポイントを逃しています
クリスストラットン14

呼び出した人がmain戻り値を取得できることを強調しています。もちろん99.9%の状況では無視されますが、答えはこの戻り値を受け取ることができる情報を提供します。
kwesolowski
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.