main()はCおよびC ++で何を返す必要がありますか?

724
Joel 2008-10-16 02:13.

main()CおよびC ++で関数を定義する正しい(最も効率的な)方法は何ですか—int main()またはvoid main()—そしてその理由は何ですか?そして、議論はどうですか?もしint main()その後、return 1またはreturn 0


この質問には、次のような多数の重複があります。

  • Cのmain()関数の有効な署名は何ですか?
  • main()関数の戻り値の型
  • 違いvoid main()int main()
  • main()C ++でのの署名
  • の適切な宣言はmain()何ですか?— C ++の場合、確かに非常に良い答えがあります。
  • main()Cの関数のスタイル
  • main()Cのメソッドの戻り値の型
  • int main()vs void main()in C

関連:

  • C ++ — int main(int argc, char **argv)
  • C ++ — int main(int argc, char *argv[])
  • であるchar *envp[]と3番目の引数としてmain()のポータブル?
  • int main()関数はすべてのコンパイラで値を返す必要がありますか?
  • main()CおよびC ++の関数のタイプをユーザーが定義する必要があるのはなぜですか?
  • なぜint main(){}コンパイルするのですか?
  • main()C ++ 14での法的定義?

18 answers

590
workmad3 2008-10-16 02:16.

の戻り値mainは、プログラムがどのように終了したかを示します。通常の終了は、からの0の戻り値で表されますmain。異常終了はゼロ以外の戻りによって通知されますが、ゼロ以外のコードがどのように解釈されるかについての標準はありません。他の人が指摘しているようにvoid main()、C ++標準では禁止されているため、使用しないでください。有効なC ++main署名は次のとおりです。

int main()

そして

int main(int argc, char* argv[])

これは

int main(int argc, char** argv)

また、C ++では、int main()returnステートメントなしで残すことができ、その時点でデフォルトで0を返すことにも注意してください。これはC99プログラムにも当てはまります。return 0;省略すべきかどうかは議論の余地があります。有効なCプログラムのメイン署名の範囲ははるかに広いです。

効率はmain機能の問題ではありません。C ++標準に従って、一度だけ入力および終了できます(プログラムの開始と終了をマークします)。Cの場合、再入力main()は許可されますが、避ける必要があります。

182
Chris Young 2008-10-16 23:59.

受け入れられた回答はC ++を対象としているように見えるので、Cに関連する回答を追加しようと思いましたが、これはいくつかの点で異なります。ISO / IEC 9899:1989(C90)とISO / IEC 9899:1999(C99)の間にもいくつかの変更が加えられました。

main() 次のいずれかとして宣言する必要があります。

int main(void)
int main(int argc, char **argv)

または同等のもの。たとえば、int main(int argc, char *argv[])は2番目のものと同等です。C90では、int戻り値の型はデフォルトであるため省略できますが、C99以降では、int戻り値の型を省略できません。

実装で許可されている場合main()は、他の方法(たとえばint main(int argc, char *argv[], char *envp[]))で宣言できますが、これによりプログラムの実装が定義され、厳密に準拠しなくなります。

:(である、実装定義された動作に依存しない)厳密に準拠していることを返すための標準的な定義3つの値を0し、EXIT_SUCCESS正常終了のため、およびEXIT_FAILURE失敗したため終了。その他の値は非標準であり、実装が定義されています。C90では、未定義の動作を回避するために、最後にmain()明示的なreturnステートメントが必要です。C99以降では、からreturnステートメントを省略できますmain()。実行してmain()終了すると、暗黙のがありreturn 0ます。

最後に、Cプログラムからmain() 再帰的に呼び出すことについては、標準の観点からは何も問題はありません。

124
Jonathan Leffler 2013-09-11 04:15.

標準C—ホスト環境

ホストされた環境(これは通常の環境)の場合、C11標準(ISO / IEC 9899:2011)は次のように述べています。

5.1.2.2.1プログラムの起動

プログラムの起動時に呼び出される関数の名前はmainです。実装は、この関数のプロトタイプを宣言していません。戻り値の型をintパラメータなしで定義する必要があります。

int main(void) { /* ... */ }

または2つのパラメーターを使用します(ここでは、argcと呼ばれますargvが、宣言されている関数に対してローカルであるため、任意の名前を使用できます)。

int main(int argc, char *argv[]) { /* ... */ }

または同等のもの; 10)または他の実装定義の方法で。

それらが宣言されている場合、main関数へのパラメーターは以下の制約に従うものとします。

  • の値はargc非負でなければなりません。
  • argv[argc] nullポインタになります。
  • 値が場合はargcゼロよりも大きい場合、アレイメンバーargv[0]によるargv[argc-1]包括的には、プログラムの起動前にホスト環境で実装定義の値が与えられた文字列へのポインタを含まなければなりません。目的は、ホストされた環境の他の場所からプログラムを起動する前に決定された情報をプログラムに提供することです。ホスト環境が大文字と小文字の両方の文字を含む文字列を提供できない場合、実装は文字列が小文字で受信されることを保証する必要があります。
  • の値がargcゼロより大きい場合、が指す文字列argv[0]はプログラム名を表します。argv[0][0]プログラム名がホスト環境から利用できない場合は、ヌル文字になります。の値がargc1より大きい場合、argv[1]throughが指す文字列argv[argc-1]はプログラムパラメータを表します。
  • 配列が指すパラメータargcargv文字列argvはプログラムによって変更可能であり、プログラムの起動から終了までの間、最後に格納された値を保持する必要があります。

10)したがって、intとして定義されたtypedef名に置き換えることができますint。または、のタイプをargvとして記述することもできますchar **argv

C99またはC11でのプログラム終了

から返された値はmain()、実装で定義された方法で「環境」に送信されます。

5.1.2.2.3プログラムの終了

1main関数の戻り値の型がと互換性のある型である場合、関数intへの最初の呼び出しからの戻り値は、関数によって返された値を引数として関数mainを呼び出すことと同じです。11)関数を終了するに達すると、値0が返されます。戻り値の型がと互換性がない場合、ホスト環境に返される終了ステータスは指定されていません。exitmain}mainint

11) 6.2.4に従って、で宣言された自動保存期間を持つオブジェクトの存続期間はmain、後者では終了しない場合でも、前者の場合で終了します。

0'成功'として義務付けられていることに注意してください。あなたは使用することができますEXIT_FAILUREし、EXIT_SUCCESSより<stdlib.h>ご希望の場合は、しかし、0が十分に確立され、その1も参照されている255より大きい終了コード-可能?。

C89(したがって、Microsoft C)では、main()関数が返される場合に何が起こるかについてのステートメントはありませんが、戻り値を指定していません。したがって、それは未定義の振る舞いにつながります。

7.22.4.4exit関数

¶5最後に、制御はホスト環境に戻されます。の値statusがゼロまたはのEXIT_SUCCESS場合、実装で定義された形式のステータス成功終了が返されます。値がいる場合statusEXIT_FAILURE、状況の実装定義フォームの失敗終了が返されます。それ以外の場合、返されるステータスは実装定義です。

標準C ++ —ホスト環境

C ++ 11標準(ISO / IEC 14882:2011)によると:

3.6.1主な機能[basic.start.main]

¶1プログラムは、プログラムの指定された開始であるmainと呼ばれるグローバル関数を含まなければならない。[...]

¶2実装は主な機能を事前に定義してはならない。この関数はオーバーロードされてはなりません。戻り値の型はint型でなければなりませんが、それ以外の場合、その型は実装定義です。すべての実装では、次のmainの定義の両方を許可する必要があります。

int main() { /* ... */ }

そして

int main(int argc, char* argv[]) { /* ... */ }

後者の形式でargcは、プログラムが実行されている環境からプログラムに渡される引数の数になります。場合はargc、これらの引数はで供給されなければならないゼロではないargv[0]を通じてargv[argc-1]、NULLで終了するマルチバイト文字列の最初の文字(NTMBSs)(17.5.2.1.4.2)へのポインタとしてとargv[0]に使用される名前を表しNTMBSの最初の文字へのポインタでなければなりませんプログラムまたはを呼び出し""ます。の値はargc負ではありません。の値はargv[argc]0でなければなりません。[注:argv。の後にさらに(オプションの)パラメーターを追加することをお勧めします。—エンドノート]

¶3この関数mainはプログラム内で使用してはならない。のリンケージ(3.5)mainは実装定義です。[...]

¶5mainのreturnステートメントは、main関数を離れ(自動保存期間を持つオブジェクトを破棄し)std::exit、引数として戻り値を使用して呼び出す効果があります。制御がreturnステートメントに遭遇せずにmainの終わりに達した場合、その効果は実行の効果です。

return 0;

C ++標準では、「[メイン関数]の戻り値の型は型intですが、それ以外の場合、その型は実装で定義されています」と明示的に規定されており、オプションとしてサポートするには、C標準と同じ2つのシグネチャが必要です。したがって、「void main()」は、C ++標準では直接許可されていませんが、代替を許可する非標準の実装を停止するためにできることは何もありません。C ++はユーザーによる呼び出しを禁止していることに注意してくださいmain(ただし、C標準では禁止されていません)。

§18.5の段落があります開始と終了§7.22.4.4から段落と同じである11標準C ++の機能C11標準では、(上記の引用された)は、(離れて脚注から、これは単に文書ことと定義されていますで)。exitEXIT_SUCCESSEXIT_FAILURE<cstdlib>

標準C—共通拡張

古典的に、Unixシステムは3番目のバリアントをサポートします。

int main(int argc, char **argv, char **envp) { ... }

3番目の引数は、文字列へのポインタのnullで終了するリストです。各ポインタは、名前、等号、および値(場合によっては空)を持つ環境変数です。これを使用しない場合でも、 ' extern char **environ;'を介して環境にアクセスできます。このグローバル変数は、それを宣言するヘッダーがないという点でPOSIXの変数の中でユニークです。

これは、付録Jに記載されている共通の拡張機能としてC標準によって認識されています。

J.5.1環境の議論

¶1ホストされた環境では、main関数は3番目の引数を受け取りchar *envp[]ますchar。これは、プログラムのこの実行のための環境に関する情報を提供する文字列を指す、nullで終了するポインタの配列を指します(5.1。 2.2.1)。

Microsoft C

マイクロソフトVS 2010コンパイラが面白いです。ウェブサイトは言う:

mainの宣言構文は次のとおりです。

 int main();

または、オプションで、

int main(int argc, char *argv[], char *envp[]);

または、mainandwmain関数をvoid戻り値(戻り値なし)として宣言することもできます。あなたが宣言した場合main、またはwmainvoidを返すように、あなたはreturn文を使って、親プロセスまたはオペレーティングシステムに終了コードを返すことができません。終了コードを返すようにする場合mainwmainとして宣言されvoid、あなたが使用する必要があり、exit機能を。

のプログラムvoid main()が終了するとどうなるか(どの終了コードが親またはOSに返されるか)は私にはわかりません—そしてMSWebサイトもサイレントです。

興味深いことに、MSはmain()、CおよびC ++標準が要求する2つの引数バージョンを規定していません。これは、3番目の引数がchar **envp環境変数のリストへのポインターである3つの引数形式のみを規定します。

Microsoftのページには、他のいくつかの選択肢もリストされています。wmain()これには、ワイド文字列などが含まれます。

このページのMicrosoftVisual Studio 2005バージョンは、代替としてリストされていません。Microsoft Visual Studio2008以降のバージョンはそうです。void main()

標準C—自立型環境

先に述べたように、上記の要件はホストされた環境に適用されます。独立した環境(ホストされた環境の代替)で作業している場合、標準は言うことがはるかに少ないです。独立した環境の場合、プログラムの起動時に呼び出される関数を呼び出す必要mainはなく、その戻り値の型に制約はありません。標準は言う:

5.1.2実行環境

独立型とホスト型の2つの実行環境が定義されています。どちらの場合も、プログラムの起動は、指定されたC関数が実行環境によって呼び出されたときに発生します。静的ストレージ期間を持つすべてのオブジェクトは、プログラムの起動前に初期化(初期値に設定)する必要があります。そのような初期化の方法とタイミングは、他の点では指定されていません。プログラムの終了により、制御が実行環境に戻ります。

5.1.2.1自立型環境

独立した環境(オペレーティングシステムの利点なしにCプログラムの実行が行われる可能性がある)では、プログラムの起動時に呼び出される関数の名前とタイプは実装によって定義されます。自立型プログラムで利用可能なライブラリー機能は、第4項で要求される最小セットを除き、実装によって定義されます。

自立型環境でのプログラム終了の影響は、実装によって定義されます。

条項4適合性への相互参照は、これを参照しています。

¶5厳密に準拠するプログラムは、この国際規格で指定されている言語とライブラリの機能のみを使用するものとします。3)未指定、未定義、または実装定義の動作に依存する出力を生成してはならず、実装の最小制限を超えてはなりません。

¶6適合実装の2つの形式は、ホストされ独立しています。準拠したホストされた実装では、任意の厳密に準拠するプログラムを受け入れるもの。適合自立実装では、ライブラリ句(項7)で指定された機能の使用は、標準ヘッダの内容に限定される任意の厳密に適合するプログラムを受け入れなければならない<float.h><iso646.h><limits.h><stdalign.h><stdarg.h><stdbool.h><stddef.h><stdint.h>、および<stdnoreturn.h>。準拠する実装には、厳密に準拠するプログラムの動作を変更しない限り、拡張機能(追加のライブラリ関数を含む)が含まれる場合があります。4)

¶7適合プログラムは、適合実装に受け入れられるプログラムです。5)

3)厳密に準拠したプログラムは、関連するマクロを使用する適切な条件付き包含前処理ディレクティブによって使用が保護されている場合、条件付き機能(6.10.8.3を参照)を使用できます。例えば:

#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
    /* ... */
    fesetround(FE_UPWARD);
    /* ... */
#endif

4)これは、適合実装がこの国際規格で明示的に予約されているもの以外の識別子を予約しないことを意味します。

5)厳密に準拠するプログラムは、準拠する実装間で最大限に移植できるようにすることを目的としています。適合プログラムは、適合実装の移植性のない機能に依存する場合があります。

関数を実際に定義する独立した環境に必要な唯一のヘッダーは<stdarg.h>(そしてそれらでさえ、単なるマクロである可能性があります)、注目に値します。

標準C ++ —独立した環境

C標準がホスト環境と独立環境の両方を認識するように、C ++標準も同様です。(ISO / IEC 14882:2011からの引用。)

1.4実装コンプライアンス[intro.compliance]

¶72種類の実装が定義されています:ホスト型実装独立型実装です。ホストされた実装の場合、この国際標準は利用可能なライブラリのセットを定義します。独立した実装とは、オペレーティングシステムを利用せずに実行できる実装であり、特定の言語サポートライブラリ(17.6.1.3)を含む実装定義のライブラリセットがあります。

¶8準拠する実装には、整形式のプログラムの動作を変更しない限り、拡張機能(追加のライブラリ関数を含む)が含まれる場合があります。この国際規格に従って不正な形式の拡張機能を使用するプログラムを診断するには、実装が必要です。ただし、そうすることで、そのようなプログラムをコンパイルして実行することができます。

¶9各実装には、サポートされていない条件付きでサポートされているすべての構成を識別し、すべてのロケール固有の特性を定義するドキュメントを含める必要があります。3

3)このドキュメントでは、実装で定義された動作も定義されています。1.9を参照してください。

17.6.1.3独立した実装[コンプライアンス]

ホスト型と自立型の2種類の実装が定義されています(1.4)。ホストされた実装の場合、この国際規格は利用可能なヘッダーのセットについて説明しています。

独立した実装には、実装で定義されたヘッダーのセットがあります。このセットには、少なくとも表16に示されているヘッダーが含まれている必要があります。

ヘッダの供給されたバージョンは、<cstdlib>少なくとも関数を宣言しなければならないabortatexitat_quick_exitexit、およびquick_exit(18.5)。この表にリストされている他のヘッダーは、ホストされた実装の場合と同じ要件を満たす必要があります。

表16—独立した実装のC ++ヘッダー

Subclause                           Header(s)
                                    <ciso646>
18.2  Types                         <cstddef>
18.3  Implementation properties     <cfloat> <limits> <climits>
18.4  Integer types                 <cstdint>
18.5  Start and termination         <cstdlib>
18.6  Dynamic memory management     <new>
18.7  Type identification           <typeinfo>
18.8  Exception handling            <exception>
18.9  Initializer lists             <initializer_list>
18.10 Other runtime support         <cstdalign> <cstdarg> <cstdbool>
20.9  Type traits                   <type_traits>
29    Atomics                       <atomic>

int main()Cでの使用はどうですか?

C11標準ショーの標準§5.1.2.2.1好ましい表記-  int main(void)-が、表示規格内の2つの例もあるint main()。§6.5.3.4¶8と§6.7.6.3¶20。ここで、例は「規範的」ではないことに注意することが重要です。それらは単なる例示です。例にバグがある場合、それらは規格のメインテキストに直接影響しません。とは言うものの、それらは予想される動作を強く示しているので、標準にint main()例が含まれている場合、それがint main()好ましい表記法でなくても、それは禁止されていないことを示唆しています。

6.5.3.4sizeofおよび_Alignof演算子

¶8例3この例では、可変長配列のサイズが計算され、関数から返されます。

#include <stddef.h>

size_t fsize3(int n)
{
    char b[n+3]; // variable length array
    return sizeof b; // execution time sizeof
}
int main()
{
    size_t size;
    size = fsize3(10); // fsize3 returns 13
    return 0;
}
61
dmityugov 2008-10-16 02:33.

私は信じているmain()のいずれかを返す必要がありますEXIT_SUCCESSEXIT_FAILURE。それらはで定義されていますstdlib.h

38
Lundin 2015-07-07 22:07.

CおよびC ++標準では、独立型とホスト型の2種類の実装が定義されていることに注意してください。

  • C90ホスト環境

    許可されるフォーム1

    int main (void)
    int main (int argc, char *argv[])
    
    main (void)
    main (int argc, char *argv[])
    /*... etc, similar forms with implicit int */
    

    コメント:

    前の2つは許可された形式として明示的に記述され、他はC90が戻り値の型と関数パラメーターに「暗黙のint」を許可したため暗黙的に許可されます。他の形式は許可されていません。

  • C90自立環境

    mainの任意の形式または名前が許可されます2

  • C99ホスト環境

    許可されたフォーム3

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    

    コメント:

    C99は「implicitint」を削除したためmain()、無効になりました。

    「または他の実装定義の方法で」奇妙で曖昧な文が導入されました。これは、「int main()変更される可能性のあるパラメーター」または「mainは実装定義の任意の形式を持つことができる」と解釈できます。

    一部のコンパイラは、後者の方法で標準を解釈することを選択しました。おそらく、標準自体があいまいであるため、標準自体を引用しても、厳密に準拠していないと簡単に述べることはできません。

    しかし、完全に野生の形を許可することmain()は、おそらく(?)この新しい文の意図ではありませんでした。C99の理論的根拠(規範的ではない)は、文がint main 4への追加パラメーターを参照していることを意味します。

    しかし、ホスト環境プログラム終了のセクションは、intを返していない主な場合について議論になります5。このセクションは、mainを宣言する方法について規範的ではありませんが、ホストされたシステムでも、mainが完全に実装定義された方法で宣言される可能性があることを明確に意味します。

  • C99自立環境

    mainの任意の形式または名前が許可されます6

  • C11ホスト環境

    許可されたフォーム7

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    
  • C11自立環境

    mainの任意の形式または名前が許可されます8


int main()上記のバージョンのいずれにおいても、Cのホストされた実装の有効なフォームとしてリストされていないことに注意してください。Cでは、C ++()(void)は異なり、異なる意味を持ちます。前者は廃止された機能であり、言語から削除される可能性があります。C11の将来の言語の方向性を参照してください。

6.11.6関数宣言子

空の括弧付きの関数宣言子(プロトタイプ形式のパラメーター型宣言子ではない)の使用は、廃止された機能です。


  • C ++ 03でホストされる環境

    許可されたフォーム9

    int main ()
    int main (int argc, char *argv[])
    

    コメント:

    最初の形式の空の括弧に注意してください。この場合、C ++とCは異なります。これは、C ++では、関数がパラメーターを受け取らないことを意味するためです。しかし、Cでは、任意のパラメーターをとることができることを意味します。

  • C ++ 03自立環境

    起動時に呼び出される関数の名前は、実装によって定義されます。名前が付けられmain()ている場合は、記載されているフォーム10に従う必要があります。

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    
  • C ++ 11でホストされる環境

    許可されたフォーム11

    int main ()
    int main (int argc, char *argv[])
    

    コメント:

    規格のテキストが変更されましたが、同じ意味です。

  • C ++ 11自立環境

    起動時に呼び出される関数の名前は、実装によって定義されます。名前が付けられmain()ている場合は、記載されているフォーム12に従う必要があります。

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    

参考文献

  1. ANSI X3.159-19892.1.2.2ホスト環境。「プログラム起動」

    プログラムの起動時に呼び出される関数の名前はmainです。実装は、この関数のプロトタイプを宣言していません。これは、戻り値の型intで、パラメーターなしで定義する必要があります。

    int main(void) { /* ... */ } 
    

    または2つのパラメーターを使用します(ここではargcおよびargvと呼びますが、宣言されている関数に対してローカルであるため、任意の名前を使用できます)。

    int main(int argc, char *argv[]) { /* ... */ }
    
  2. ANSI X3.159-1989 2.1.2.1自立型環境:

    独立した環境(オペレーティングシステムの利点なしにCプログラムの実行が行われる可能性がある)では、プログラムの起動時に呼び出される関数の名前とタイプは実装によって定義されます。

  3. ISO 9899:19995.1.2.2ホスト環境-> 5.1.2.2.1プログラムの起動

    プログラムの起動時に呼び出される関数の名前はmainです。実装は、この関数のプロトタイプを宣言していません。これは、戻り値の型intで、パラメーターなしで定義する必要があります。

    int main(void) { /* ... */ } 
    

    または2つのパラメーターを使用します(ここではargcおよびargvと呼びますが、宣言されている関数に対してローカルであるため、任意の名前を使用できます)。

    int main(int argc, char *argv[]) { /* ... */ }
    

    または同等のもの; 9)または他の実装定義の方法で。

  4. 国際標準の理論的根拠—プログラミング言語— C、リビジョン5.10。5.1.2.2ホスト環境-> 5.1.2.2.1プログラムの起動

    mainへの引数の動作、およびexit、main、atexitの相互作用(§7.20.4.2を参照)は、argv文字列の表現、およびmainによって返される値の意味におけるいくつかの不要な多様性を抑制するために体系化されています。

    mainへの引数としてargcとargvを指定すると、広範な先行プラクティスが認識されます。argv [argc]は、これも一般的な方法に基づいて、リストの最後に冗長チェックを提供するためにnullポインターである必要があります。

    mainは、ゼロまたは2つの引数を使用して移植可能に宣言できる唯一の関数です。(他の関数の引数の数は、呼び出しと定義の間で正確に一致する必要があります。)この特殊なケースは、プログラムがプログラムの引数文字列にアクセスしないときに、引数をmainに残しておくという広範な慣行を単に認識しています。多くの実装はmainに対して3つ以上の引数をサポートしていますが、そのような慣行は標準によって祝福も禁止もされていません。3つの引数でmainを定義するプログラムは、厳密には準拠していません(§J.5.1を参照)。

  5. ISO 9899:19995.1.2.2ホスト環境-> 5.1.2.2.3プログラムの終了

    main関数の戻り値の型がintと互換性のある型である場合、main関数への最初の呼び出しからの戻り値は、main関数によって返された値を引数としてexit関数を呼び出すことと同じです。11)}終了するに到達します。 main関数は値0を返します。戻り値の型がintと互換性がない場合、ホスト環境に返される終了ステータスは指定されていません。

  6. ISO 9899:19995.1.2.1自立型環境

    独立した環境(オペレーティングシステムの利点なしにCプログラムの実行が行われる可能性がある)では、プログラムの起動時に呼び出される関数の名前とタイプは実装によって定義されます。

  7. ISO 9899:20115.1.2.2ホスト環境-> 5.1.2.2.1プログラムの起動

    このセクションは、上記のC99と同じです。

  8. ISO 9899:19995.1.2.1自立型環境

    このセクションは、上記のC99と同じです。

  9. ISO 14882:20033.6.1主な機能

    実装は、主な機能を事前に定義してはなりません。この関数はオーバーロードされてはなりません。戻り値の型はint型でなければなりませんが、それ以外の場合、その型は実装定義です。すべての実装では、次のmainの定義の両方を許可する必要があります。

    int main() { /* ... */ }
    

    そして

    int main(int argc, char* argv[]) { /* ... */ }
    
  10. ISO 14882:20033.6.1主な機能

    メイン関数を定義するために独立した環境のプログラムが必要かどうかは、実装によって定義されます。

  11. ISO 14882:20113.6.1主な機能

    実装は、主な機能を事前に定義してはなりません。この関数はオーバーロードされてはなりません。戻り値の型はint型でなければなりませんが、それ以外の場合、その型は実装定義です。すべての実装で両方が許可されます

    —()がintとを返す関数

    — intを返す(int、charへのポインタへのポインタ)の関数

    メインのタイプとして(8.3.5)。

  12. ISO 14882:20113.6.1主な機能

    このセクションは、上記のC ++ 03と同じです。

29
Lou Franco 2008-10-16 02:16.

成功した場合は0を返し、エラーの場合はゼロ以外を返します。これは、プログラムで何が起こったかを調べるためにUNIXおよびDOSスクリプトで使用される標準です。

8
Jeegar Patel 2011-12-27 22:02.

main() C89およびK&R Cでは、指定されていない戻り値の型はデフォルトで 'int`になります。

return 1? return 0?
  1. にreturnステートメントを記述しない場合int main()、終了{はデフォルトで0を返します。

  2. return 0またはreturn 1、親プロセスによって受信されます。シェルでは、シェル変数に入ります。プログラムをシェルから実行していて、その変数を使用していない場合は、の戻り値について心配する必要はありませんmain()

メイン関数が返したものを取得するにはどうすればよいですか?を参照してください。。

$ ./a.out $ echo $?

このようにして$?、の戻り値の最下位バイトを受け取るのは変数であることがわかりますmain()

UnixおよびDOSスクリプトでreturn 0は、通常、成功するとゼロ以外のエラーが返されます。これは、UnixおよびDOSスクリプトで使用される標準であり、プログラムで何が起こったかを調べ、フロー全体を制御します。

7
Ferruccio 2008-10-16 05:22.

intを返している場合でも、一部のOS(Windows)は、返された値を1バイト(0〜255)に切り捨てることに注意してください。

4
Yochai Timmer 2011-07-02 06:32.

オペレーティングシステムは戻り値を使用して、プログラムがどのように閉じられたかを確認できます。

戻り値0は通常、ほとんどのオペレーティングシステム(とにかく私が考えることができるもの)でOKを意味します。

また、自分でプロセスを呼び出すときにチェックして、プログラムが終了して正しく終了したかどうかを確認することもできます。

これは単なるプログラミング規約ではありません

3
Noname 2011-07-02 13:30.

の戻り値はmain()、プログラムがどのように終了したかを示します。戻り値がのzero場合は、実行が成功したことを意味しますが、ゼロ以外の値は、実行で問題が発生したことを示します。

2
graham.reeds 2008-10-16 02:42.

成功したリターンはOSベースであるため(一方がゼロの場合は成功または失敗のいずれかである可能性があるため)、標準ではmainに戻り値は必要ないと指定されているという印象を受けました。したがって、リターンがないことが手がかりでした。正常な戻り値自体を挿入するコンパイラ。

ただし、通常は0を返します。

2
Vamsi Pavan Mahesh 2012-11-23 21:29.

0を返すと、プログラムがジョブを正常に終了したことがプログラマーに通知されます。

2
Edward 2017-04-23 01:34.

省略 return 0

CまたはC ++プログラムが最後に到達するとmain、コンパイラは0を返すコードを自動的に生成するためreturn 0;、の最後に明示的に配置する必要はありませんmain

注:私がこの提案をするとき、それはほとんど常に2種類のコメントのうちの1つが続きます:「私はそれを知りませんでした」。または「それは悪いアドバイスです!」私の理論的根拠は、標準で明示的にサポートされているコンパイラの動作に依存することが安全で便利であるということです。Cの場合、C99以降。ISO / IEC 9899:1999セクション5.1.2.2.3を参照してください。

[...]main関数への最初の呼び出しからのexit戻りは、main関数によって返された値を引数として関数を呼び出すことと同じです。関数}を終了するに達すると、main値0が返されます。

C ++の場合、1998年の最初の標準以降。ISO / IEC 14882:1998セクション3.6.1を参照してください。

制御がreturnステートメントに遭遇せずにmainの終わりに達した場合、その効果はreturn0を実行することです。

それ以降、両方の標準のすべてのバージョン(C99およびC ++ 98)は同じ考えを維持しています。C ++で自動生成されたメンバー関数に依存しておりreturn;void関数の最後に明示的なステートメントを作成する人はほとんどいません。省略した理由は、「奇妙に見える」に要約されるようです。私のように、C標準への変更の理由について知りたい場合は、この質問を読んでください。また、1990年代初頭には、当時は未定義の動作であったため(広くサポートされていましたが)、これは「ずさんな慣行」と見なされていたことにも注意してください。

さらに、C ++コアガイドラインにはreturn 0;、最後に省略の複数のインスタンスが含まmainれており、明示的な戻り値が書き込まれるインスタンスは含まれていません。その文書にはこの特定のトピックに関する特定のガイドラインはまだありませんが、それは少なくとも実践の暗黙の承認のようです。

だから私はそれを省略することを提唱します。他の人は同意しません(しばしば激しく!)いずれにせよ、それを省略したコードに遭遇した場合、それが標準によって明示的にサポートされていることがわかり、それが何を意味するかがわかります。

1
phoxis 2011-03-11 04:11.

何を返すかは、実行可能ファイルで何をしたいかによって異なります。たとえば、コマンドラインシェルでプログラムを使用している場合、成功した場合は0を返し、失敗した場合はゼロ以外を返す必要があります。そうすれば、コードの結果に応じて、条件付き処理を使用してシェルでプログラムを使用できるようになります。また、解釈に従ってゼロ以外の値を割り当てることもできます。たとえば、重大なエラーの場合、異なるプログラム出口点が異なる出口値でプログラムを終了する可能性があり、返された値を調べて何をするかを決定できる呼び出し元のシェルで使用できます。コードがシェルでの使用を目的としておらず、戻り値が誰にも迷惑をかけない場合は、省略される可能性があります。私は個人的に署名を使用しますint main (void) { .. return 0; .. }

1
Luca C. 2011-03-04 01:56.

プロセスから整数を返す効率に関連する問題が本当にある場合は、この戻り値が問題になるほどそのプロセスを何度も呼び出すことは避けてください。

これを行う場合(プロセスを何度も呼び出す)、呼び出しごとに特定のプロセスを割り当てることなく、ロジックを呼び出し元内に直接配置するか、DLLファイルに配置する方法を見つける必要があります。この場合、複数のプロセス割り当てにより、関連する効率の問題が発生します。

詳細には、0を返す方が1を返すよりも効率が良いか低いかだけを知りたい場合は、コンパイラに依存する場合もありますが、一般的には、同じソース(ローカル、フィールド、定数、埋め込み)から読み取られると仮定します。コード、関数の結果など)では、まったく同じクロックサイクル数が必要です。

1
rbaleksandar 2015-02-11 12:22.

これは、リターンコードの使用法の簡単なデモンストレーションです...

Linuxターミナルが提供するさまざまなツールを使用する場合、たとえば、プロセスが完了した後のエラー処理にリターンコードを使用できます。次のテキストファイルmyfileが存在するとします。

これは、grepがどのように機能するかを確認するためのいくつかの例です。

grepコマンドを実行すると、プロセスが作成されます。完了すると(そして壊れなかった場合)、0から255までのコードが返されます。次に例を示します。

$ grep order myfile

もしあなたがそうするなら

$ echo $? $ 0

あなたは0を得るでしょう。なぜですか?grepが一致を検出し、終了コード0を返したためです。これは、成功して終了するための通常の値です。もう一度チェックしてみましょう。ただし、テキストファイル内にないため、一致するものが見つかりません。

$ grep foo myfile $ echo $? $ 1

grepがトークン「foo」をファイルの内容と一致させなかったため、戻りコードは1です(これは失敗が発生した場合の通常のケースですが、上記のように、選択できる値がたくさんあります)。

次のbashスクリプト(Linuxターミナルに入力するだけです)は、非常に基本的なものですが、エラー処理についてある程度理解できるはずです。

$ grep foo myfile $ CHECK=$? $ [ $CHECK -eq 0] && echo 'Match found' $ [ $CHECK -ne 0] && echo 'No match was found' $ No match was found

2行目以降は、「foo」がgrepに1を返し、grepの戻りコードが0に等しいかどうかを確認するため、端末に何も出力されません。2番目の条件ステートメントは、CHECKによりtrueであるため、最後の行にメッセージをエコーし​​ます。 == 1。

これとそのプロセスを呼び出しているかどうかを確認できるように、(main()の戻り値によって)何が返されたかを確認することが不可欠な場合があります。

1
Steve Summit 2017-10-04 11:56.

CおよびC ++でmain()関数を定義する正しい(最も効率的な)方法は何ですか— int main()またはvoid main()—そしてその理由は何ですか?

「(最も効率的)」という言葉は問題を変えません。自立型の環境にいない限り、宣言するための普遍的に正しい方法が1つあり、それはmain()intを返すことです。

main()CおよびC ++では何を返す必要がありますか?

それは何ではないはずです main()、それは何だ、返さない main()リターンを。main()もちろん、他の誰かが呼び出す関数です。を呼び出すコードを制御することはできませんmain()。したがって、main()呼び出し元と一致するように、タイプが正しい署名で宣言する必要があります。あなたは単にその問題に関して選択の余地がありません。答えはCおよびC +標準によってすでに完全に定義されているため、効率が高いか低いか、スタイルが良いか悪いかなどを自問する必要はありません。それらに従ってください。

int main()の場合、1を返すか0を返しますか?

成功の場合は0、失敗の場合はゼロ以外。繰り返しますが、選択する(または取得する)必要のあるものではありません。準拠する必要のあるインターフェイスによって定義されます。

0
gsamaras 2020-10-11 05:34.

Cでは、C11標準のセクション5.1.2.2.1(私の強調):

戻り値の型をintパラメータなし定義する必要があります。

int main(void) { /* ... */ }

または2つのパラメーターを使用します(ここでは、argcと呼ばれますargvが、宣言されている関数に対してローカルであるため、任意の名前を使用できます)。

int main(int argc, char *argv[]) { /* ... */ }

しかし、私のような一部の初心者にとっては、抽象的な例でそれを把握することができます。

たとえばint read_file(char filename[LEN]);、プログラムでメソッドを作成するときは、このメソッドの呼び出し元として、すべてがうまくいったかどうかを知りたいと思います(ファイルが見つからなかったなどの障害が発生する可能性があるため)。メソッドの戻り値をチェックすることで、すべてがうまくいったかどうかを知ることができます。これは、メソッドが正常に実行されたかどうかを通知し、呼び出し元(メインメソッドなど)に決定させるメカニズムです。予期しない障害を処理する方法。

それで、今、私がより複雑なシステムで使用されるマイクロメカニズムのためのCプログラムを書くと想像してください。システムがマイクロメカニズムを呼び出すとき、システムはすべてが期待どおりに進んだかどうかを知りたいので、潜在的なエラーを処理できます。Cプログラムのメインメソッドがvoidを返す場合、呼び出し側システムはそのサブシステム(マイクロメカニズム)の実行についてどのように知るのでしょうか?実行が成功した(または失敗した)ことを呼び出し元に通知するために、main()がintを返すのはそのためです。

言い換えると:

その理由は、ホスト環境(つまり、オペレーティングシステム(OS))は、プログラムが正しく終了したかどうかを知る必要があるということです。戻り値の型としてint互換の型(例:void)がない場合、「ホスト環境に返されるステータスは指定されていません」(つまり、ほとんどのOSで未定義の動作)。

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする&nbsp;

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

2021 年 6 月 8 日にニューヨーク市で開催された covid-19 パンデミックで亡くなった人々の命を偲び、祝うために、ネーミング ザ ロスト メモリアルズが主催するイベントと行進の最中に、グリーンウッド墓地の正門から記念碑がぶら下がっています。週末、ジョー・バイデン大統領は、covid-19 パンデミックの終息を宣言しました。これは、過去 2 年以上にわたり、公の場でそうするための長い列の中で最新のものです。

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

オハイオ州のエミリー・デシャネル みんな早く来て、ボーンズが帰ってきた!まあ、ショーボーンズではなく、彼女を演じた俳優. エミリー・デシャネルに最後に会ってからしばらく経ちました.Emily Deschanel は、長期にわたるプロシージャルな Bones の Temperance “Bones” Brennan としてよく知られています。

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

どうやら、ドナルド・トランプに近い人々は、今月初めにFBIによって家宅捜索された彼のMar-a-Lago財産からの映像を公開するよう彼に勧めています. 前大統領はテープを公開するかどうかを確認していませんが、息子はフォックス・ニュースにそうなるだろうと語った.

Andor は、他の Star Wars ショーから大きな距離を置きます。

Andor は、他の Star Wars ショーから大きな距離を置きます。

アンドールの一場面。数十年前、ジョージ・ルーカスがスター・ウォーズのテレビ番組を制作するのを妨げた主な理由は、お金でした。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language