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

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

int main()

そして

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

これは

と同等です
int main(int argc, char** argv)

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

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


受け入れられた回答は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 つの値を定義しています:0EXIT_SUCCESS 成功した終了の場合、および EXIT_FAILURE 失敗した終了のために。その他の値は非標準であり、実装によって定義されます。 C90 では、main() 明示的な return が必要です 未定義の動作を避けるために最後にステートメントを追加します。 C99 以降では、main() から return ステートメントを省略できます。 .もしそうなら、そして main() 終了、暗黙の return 0 があります .

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


標準 C — ホスト環境

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

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

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

0 に注意してください 「成功」として義務付けられています。 EXIT_FAILURE を使用できます と EXIT_SUCCESS <stdlib.h> から 必要に応じて、0 が十分に確立されており、1 も確立されています。255 より大きい終了コードも参照してください — 可能性はありますか?

C89 (したがって Microsoft C) では、main() の場合に何が起こるかについての記述はありません。 関数は戻りますが、戻り値を指定しません。したがって、未定義の動作につながります。

標準 C++ — ホスト環境

C++11 標準 (ISO/IEC 14882:2011) には次のように記載されています。

C++ 標準では、「[メイン関数] は int 型の戻り値の型を持つ」と明示的に述べています。 、しかしそれ以外の場合、その型は実装定義されています」、およびオプションとしてサポートされる C 標準と同じ 2 つの署名が必要です。代替手段を許可する非標準の実装を停止します。C++ では、ユーザーが main を呼び出すことを禁止していることに注意してください。 (しかし、C 標準はそうではありません)。

§18.5 開始と終了の段落があります §7.22.4.4 The exit の段落と同一の C++11 標準で 関数 C11 標準 (上で引用) では、脚注 (これは EXIT_SUCCESS を単純に文書化したもの) を除いて と EXIT_FAILURE <cstdlib> で定義されています ).

標準 C — 共通の拡張子

従来、Unix システムは 3 番目のバリアントをサポートしています:

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

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

これは、附属書 J に記載されている一般的な拡張機能として C 標準によって認識されています。

Microsoft C

Microsoft VS 2010 コンパイラは興味深いものです。 Web サイトには次のように書かれています:

void main() のプログラムが 終了します — MS の Web サイトも沈黙しています。

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

Microsoft のページには、他の代替手段もいくつかリストされています — wmain() ワイド文字列などを取ります。

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

標準 C — 自立型環境

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

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

実際に関数を定義する独立した環境に必要なヘッダーは <stdarg.h> だけであることに注目してください。 (そして、それらでさえ、マクロである可能性があり、多くの場合、マクロです)。

標準 C++ — フリースタンディング環境

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

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

C11 標準の標準 §5.1.2.2.1 は、推奨される表記法 — int main(void) を示しています。 — しかし、標準には int main() を示す 2 つの例もあります :§6.5.3.4 ¶8 および §6.7.6.3 ¶20。ここで、例は「規範的」ではないことに注意することが重要です。それらは単なる説明です。例にバグがあっても、標準の本文には直接影響しません。とはいえ、それらは予想される動作を強く示しているため、標準に int main() が含まれている場合 例では、 int main() を示唆しています 好ましい表記法でなくても、禁止されていません。