2012-01-21 8 views
2

新しいプロセスはfork/execによって作成されます。 Execはコマンドラインの引数を設定しますが、それらの引数の数がargcに設定されていることはわかりません。argcはどこから来たのですか?

main()は、新しいプロセスで実行する最初の機能であると想定されていますが、argcはすでに設定されています。

どこに設定されていますか? mainが呼び出される前にパラメータを数える何らかの設定コードでなければなりませんが、私が読んだことは何も、このセットアップコードが何をしているのか、それがどこにあるのかを説明するものは何もありません。

これはlibcですか?これはすべてのOSで同じですか、いくつかの仕様でカバーされていますか?これ以外にセットアップコードで何が起きているのかはどこで分かりますか?グローバルをインスタンス化する前に呼び出されますか?

+0

あなたはどの言語に興味がありますか? –

+1

言語仕様では、mainが実行されるまでに何が行われているかが詳しく説明されています。見つけ出すためにそれらを読んでください。 OSによって行われることと、言語ランタイムによって行われることは、実装によって異なります。あなたの質問は少し曖昧なので、もっと言いにくいです。これは非常に大きな話題であり、実装に固有のものです。 –

+0

これはシステムに非常に依存しています。例えばLinuxは、カーネル内のexecveシステムコール(do_execve()関数)内のargvの項目を数えます。 – nos

答えて

6

mainが呼び出される前に、ほとんどの実装で起こることがたくさんあります(通常、環境はCランタイムの起動であるcrt0に似ています)。

など、リソースの閉鎖などmain後に終了し、atexit終了ハンドラとを起こるかもしれものがたくさんもあります。

Cの標準は、実際には言語の観点から行われるものだけをカバーしています。実装がどのようにカバーの下で作業しているのか(基本的にはあなたが求めているものです)ではありません。それぞれの実装はさまざまな方法で処理を行うことができますが、多くのUNIXタイプには前述のようなものがあります(crt0)。

+1

したがって、main()なしで実行可能ファイルをコンパイルしようとすると、crt0リンクのエラーが発生します。面白いことに、これはOS仕様と言語仕様の間の土地ではないようです。優れた!ありがとう。 –

+0

@sean全く面白くない。すべてのシステムがプロセスを異なる方法で扱います。標準は共通のインターフェースを提供します。当然のことながら、言語の各実装は、OSプロセスの開始と 'main()'の開始との間の実装固有の橋渡しを提供しなければなりません。実際には、これはスペックがすべて正確に何であるかということです。 4つのパラメータを持つWindowsプログラムの主な機能を見てみましょう。そのスタイルはC標準が出る前に存在し、標準準拠の主な機能ではありません。 –

+0

@DavidHeffernan Cについてはわかりませんが、C++では 'main'が標準に準拠しています。標準では実装が*少なくとも引数と2つの引数バージョンを提供する必要がありますが、明示的にargc/argvの後ろに余分な引数を入れるべきであることを明示しています。いずれにしても、戻り値の型は 'int'である必要があります。 –

0

OSが処理します。結局のところ、それはスレッドとプロセスを処理するOSです。

+1

いいえ、それは言語ランタイムの仕事です。 –

+0

@DavidHeffernan:うーん、プラットフォームに依存していると思います。 –

+0

@MatteoItalia「これ以外にセットアップコードで何が起きているのでしょうか?グローバルをインスタンス化する前に呼び出されていますか?それはランタイムまで下がる必要があります。 –

0

フォークを使用すると、次のコード行で処理が続行されます。 Exec関数ファミリは、関数の2番目のパラメータを使用している場合に応じてパラメータの配列である新しい実行を作成します。 CおよびC++で

#include <unistd.h> 


int ret; 
char *cmd[] = { "ls", "-l", (char *)0 }; 
char *env[] = { "HOME=/usr/home", "LOGNAME=home", (char *)0 }; 
... 
ret = execve ("/bin/ls", cmd, env); 
0

main()mainCRTStartup()たり、ビルドツールに依存して、同様の機能から呼び出されます。デバッガを起動して呼び出しスタックを調べると、ソースを見つけることができるはずです。

関連する問題