「main」がintまたはvoidではなくdoubleまたはStringを返すことができないのはなぜですか?


38

例えばC、C ++、およびJavaなどの多くの言語では、main方法/機能は、の戻り型有しvoidまたはintではなく、doubleまたはString。その背後にある理由は何ですか?

main実行時ライブラリによって呼び出されint main()int main(int,char**)そのようないくつかの構文を想定しているため、それを実行できないことを少し知っています。

だから私の質問は次のとおりです。なぜそれがmain持っているタイプ署名を持っており、別のものではないのですか?


15
二重の戻り値は何をでしょう意味しますか?文字列の戻り値はどういう意味ですか?

1
kiは何の意味もないことを理解していますが、他の理由や慣習はありますか?
JAVA

1
私はそれが何も意味しないと思います、単に通常終了のために0と異常のために非ゼロが選択されたからです。intは広範なクロス言語互換性を持つ最も単純なデータ型として選択されました。@ delnan
JAVA

@sunny UnixライクなOSでの経験から集めたものから、0は他の整数値と比較して明確であるため、「正常終了」(0エラー)として使用されます。ほとんどの(すべてではない)現代言語はCに似ているように設計されているので(Cの背面で設計されていない場合)、CがUnixの記述に使用されているため、KnRによる歴史的な決定でした。
ジェイミーテイラー

3
@sunny「幅広い言語間互換性」は問題ではありませんでした。CとUNIXは並行して作成されました。他の多くの言語がintを返すのは、それらがUNIXまたはUNIXライクな環境で動作するように設計されているためです。

回答:


83

の戻り値は、単一の一貫した方法でmainオペレーティングシステム(任意のオペレーティングシステム)に渡されます。オペレーティングシステムが知る必要がある情報は、「プログラムが正常に終了したか、エラーがありましたか?」です。

これが文字列の場合、異なる言語では応答が困難になります。Pascal文字列(最初のバイトは長さ)とFORTRAN文字列(固定され、ある値に埋め込まれる)とC文字列(nullで終わる)の内部はすべて異なります。これにより、オペレーティングシステムに一貫した値を返すことが難しくなります。これが解決されたと仮定して、OSがプログラムに関して持っていた質問に答えるために何をしますか?文字列の比較にはエラー(「成功」と「成功」)が伴い、エラーは人間にとってはより有用かもしれませんが、オペレーティングシステムや他のプログラム(シェル)が対処するのはより困難です。また、文字列自体にも大きな違いがありました-EBCDIC(すべてのコードページ)とASCII。

浮動小数点数と倍精度数は、OS(およびシェル)とデータをやり取りするための整数以上の追加値を提供しません。ほとんどの場合、コンピューターのこれらの部分はどちらも浮動小数点数を処理しません。また、倍精度は列挙可能ではなく、比較が困難です。列挙できないため、エラーの内容を報告します(成功のために特定の値を選択したと仮定します)。繰り返しますが、浮動小数点は一貫性がありません-8ビットマシンのフロートは16ビットおよび32ビットマシンのフロートとは異なりました(そしてこれらは単なる「通常の」ものです-IBM内でも、浮動小数点は標準化されていませんでした) 1980年代までの同じメーカーのマシン間)。そして、10進数コンピューターと2進数コンピューターがあります。浮動小数点値は一貫性がなく、意味のあるデータを提供しません。

これにより、バイトと整数がオプションとして残ります。確立された規則は「0」が成功であり、それ以外はエラーでした。整数は、エラーを報告するために1バイト以上のスペースを与えます。それは、(1つの手段XYZの復帰、2つの手段DEF ABC、3の復帰は、手段のリターン、等。)に列挙またはフラグ(として使用することができる0x0001手段、これは失敗し、0x0002失敗した手段、0x0003手段本とその失敗の両方)。これを1バイトに制限すると、フラグ(8個のみ)が簡単に不足する可能性があるため、おそらく整数を使用することを決定しました。


2
mainは、osを呼び出す前にc / c ++ランタイムライブラリによって呼び出されると思います。これは、コードとともに読み込まれ、os @ MichaelT
JAVA

5
main()オペレーティングシステムごとに異なる方法で呼び出されます。 Cでは、main()メソッドは最初にどのように呼び出されますか?これに入ります。

22
理解すべき重要な点は、main他のプログラムの他の機能とは異なり、プログラマによって定義されたプロトコルの一部ではなく、ホスト(OS)とのインターフェイスに使用されるプロトコルであると思います。あなたが選ぶのは決してあなたでなかったので、あなたはそれを選ぶことができません。より実用的なレベルでは、UNIXはintがプロセスによって返されることを期待しているため、C-to-UNIXプロトコルはまさにそれを行います。引数の受け渡しについても同様の引数を作成できます。引数として数値のみを渡す(コマンドラインなしなど)OS /ホスト用にCが発明された場合、引数は文字列ではなくintになります。
ユーロミチェリ

2
IBMは、コードページの概念をEBCDICからPCに取り入れました。IBM 5150の導入から35年経った今でも、彼らは私たちを悩ませています。7ビットASCIIはコードページレスですが、8ビット文字コードは、設定によっては1台のコンピューターでもさまざまな方法で解釈できます- -マルチバイトエンコーディングをコードするコードページはもちろんです。したがって、実際には、2番目の段落の最後の文で暗示するものよりもさらに悪いです。
CVn

@EuroMicelliそれは非常に素晴らしい情報です、実際に感謝します:)
JAVA

27

まあ、それはできました

たとえば、Plan 9オペレーティングシステムで使用されるCの方言でmainは、通常、void関数として宣言されますが、exits()関数に文字列ポインターを渡すことにより、終了ステータスが呼び出し環境に返されます。空の文字列は成功を示し、空でない文字列は何らかの失敗を示します。これmainchar*結果を返すことで実装できます。

また、システムを終了ステータスfloatまたはdouble終了ステータスで実装することは確かに可能です。

だからなぜint?それは単なる慣習の問題です-そして、それらの下で実行されるオペレーティングシステムとプログラムが共通の慣習に従うことには大きな価値があります。

Unixの慣習では、整数のステータスコードを使用します。0は成功を表し、0は失敗を表します(通常、成功する方法は1つだけですが、失敗する方法は複数あるため)。その慣習がUnixに由来しているかどうかはわかりません。以前のオペレーティングシステムから来たのではないかと思います。

(a)浮動小数点サポートは普遍的ではないため、(b)浮動小数点値とエラー条件の間のマッピングを定義することはより困難であるため、(c)異なるシステムは異なる浮動小数点を使用するため、 (d)プログラムの終了ステータスの丸めエラーを追跡する楽しみを想像してください。一方、整数はエラーコードの列挙に非常に役立ちます。

プラン9は、前述のとおり文字列を使用しますが、メモリ管理、文字エンコードなどに多少の複雑さを課します。これは、プラン9が実装した新しいアイデアであり、既存のものに置き換わるものではありませんでした。広範な慣習。

(C ++で尚は、mainできるだけ返しint、及びCでvoid mainあなたが書いた場合、多くのコンパイラは非常に大声で文句を言わない。コンパイラは、具体的にそれをサポートしている場合にのみ許可されているvoid mainが、それはそれのことを言ってわずかな誇張だ間違っています。)


9

mainメソッドによって返される値は「終了コード」です。呼び出し元のアプリケーション(通常はbash)によって使用され、プログラムが期待どおりに終了したかどうかをテストします。OSレベルで整数を返すのが最も簡単な方法です。Doubleはエラーコードには意味がなく、文字列はOSレベルで維持するのが困難です(GCはありません)。


3
整数ではなく文字列をガベージコレクションする必要があるのはなぜですか?
ブラッド

4
@Brad、文字列には可変長があり、本質的には、1文字または数千の配列を返すのと同じです。動的メモリは苦痛になりますが、intはかなり固定されたサイズであり、取り扱いがそれほど難しくありません。
JBキング
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.