2

重複の可能性:
main() は C/C++ で何を返す必要がありますか?

#include<stdio.h>
int main()
{
    return 0;
}

上記のコード スニペットでは、main によって返された return 0 はどこに行くのでしょうか? 言い換えれば、どの関数が最初にメイン関数を呼び出したかということです。

4

4 に答える 4

12

mainC ランタイム ライブラリの起動関数によって呼び出されます。C 言語標準では、から戻るmainことは関数を呼び出すことと同等であると述べているexitため、ほとんどの C ランタイムは次のようになります。

void _start(void)  /* Exact function signature may vary */
{
    /* Platform-specifi startup (e.g. fetch argc and argv from the OS) */
    ...
    int status = main(argc, argv);
    exit(status);
    /* Never reached */
}

終了ステータスはオペレーティング システムに戻され、そこから何が起こるかは OS に依存します。

プログラムをコンパイルしてリンクすると、実行可能ファイル形式 (PE または ELF など) に開始アドレスが含まれます。これは、実行が開始される仮想アドレスです。その関数は通常、C ランタイム ライブラリの一部です (_start上記の例のように)。その関数は、 などのシステム コールを呼び出して終了するexit必要があります。これは、返されたばかりの場合、移動先がないためです。スタックからアドレスをポップしてその場所にジャンプするだけで、ゴミになります。

OS ローダーがプロセスを初期化する方法に応じて、プログラム引数argcargv、およびその他のデータ (環境など) が関数パラメーターとして (レジスターまたはスタックを介して) 取り込まれるか、システム コールが必要になる場合があります ( GetCommandLineWindows など)。それらを取得します。しかし、そのすべてを処理するのは C ランタイムの仕事であり、C ランタイムの使用を避けるために明示的に道を外れている場合を除き、これらの詳細について心配する必要はありません。

于 2012-11-02T18:24:14.407 に答える
3

コンパイラは、プロセスを開始するためのオペレーティング システム固有のメカニズムを含む特定のプラットフォームを対象としています。そのプラットフォーム固有のコードの一部には、 の戻り値が含まれていますmain。プログラムを実行可能ファイルにリンクすると、リンカが追加する OS 固有のバイナリ コードがありmain、オペレーティング システムに戻り値を呼び出して報告します。

于 2012-11-02T18:24:41.490 に答える
2

戻り値は、ホストされた環境に送られます。通常、オペレーティング システムはmain、プログラムの終了ステータスを呼び出して取得します。

于 2012-11-02T18:24:42.123 に答える
0

main から返された return 0 はどこに行くのですか? 言い換えれば、どの関数が最初にメイン関数を呼び出したかということです。

これは、カーネルによって (ほぼ) 直接呼び出されるスタブ関数である C スタートアップ ライブラリによって呼び出されます。たとえば、Linux と OS X では、という名前の関数_startです。と同じシグネチャをmain()持ち、オペレーティング システム自体がその戻り値を使用します。

于 2012-11-02T18:25:27.337 に答える