#C++ なぜ int main()と書くのか?
C++の勉強を最近始めました。
ふと思ったのですが書籍等では、main関数の宣言時に戻り値の指定を基本的にintと書いてあります。
こんな感じです
C++
1#include<iostream> 2using namespace std; 3 4int main() 5{ 6... 7 8return 0; 9}
これを書いていて思ったのですが、戻り値にintを指定して、
return 0;を返すことに意味はあるのでしょうか?
初学者の私はJavaみたいにvoidで戻り値を指定しておけば良くない??
と思ってしまったのですが、
このことについて何かしらのアドバイスをいただけたらと思います。
初歩的な質問で申し訳ございませんが、よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答8件
0
ベストアンサー
main
関数からの戻り値はプロセスの終了ステータスになります。
プログラムの中にはプログラムの内部でプログラムを実行する(Cであればsystem
関数等)場合があります。呼び出す側のプロセスを親プロセス、呼び出される側のプロセスを子プロセスと言います。あるプログラムAが実行され、そのプロセスが動作中に、別のプログラムBを内部で実行したとしましょう。その時、プロセスは親子関係にあり、親プロセスではプログラムAが、子プロセスではプログラムBが動作することになります。プログラムBのコードを全て実行し、子プロセスが終了したとします。そのとき、子プロセスは親プロセスに終了ステータスを渡します。プログラムAではその終了ステータスによって動作を分岐させることができます。
この終了ステータスは整数値(とり得る範囲は環境によって異なる)で、ほとんどの環境では0が成功終了(正常終了)です。Cでは、この終了ステータスを簡単に返せるようにと、main
関数の戻り値によって、どんな終了ステータスで終了したかを選べるようにしています。Cの中でも、0が成功終了を意味しており、return 0;
となっている場合は、そのプロセスは成功終了を意味する終了ステータスを渡すようになっています。
なお、exit
関数で即座に完了することもでき、exit
関数への引数も同じように解釈されます。(逆に言うと、return 0;
はexit(0);
と同じです。)
C++はCの拡張であるため、Cのこの仕様を引き継いでおり、同様の動作となります。
FAQ
- 成功終了を表す終了ステータスが0以外の環境(存在するかは不明)で、
return 0;
とした場合は、異常終了になるのですか?
いいえ、0またはEXIT_SUCCESS
(成功終了を表すマクロ、0とは限りない)をmain
でreturn(またはexit関数に渡す)した場合、その処理系における成功終了を表す終了ステータスになります。main
のreturn 0;
はどのような状況においても、成功終了を意味します。
2. 0以外は異常終了なのですか?
Cの仕様で定義されているのはEXIT_FAILURE
の場合に失敗終了を意味するということだけです。それ以外は処理依存になります。ただし、ほとんどの処理系では、0-255の範囲ではそのまま終了ステータスになり、0以外は異常とみなされます。
3. return 0;
を省略しましたが、正常終了しました。バグですか?
戻り値がvoid
ではない関数の中で、唯一main
関数のみreturn
を省略出来ます。省略された場合は、一番最後にreturn 0;
が存在するとみなされます。
4. どういうときに使うのですか?
特にシェルで多用します。prog_1 && prog_2
と書くと、prog_1が成功終了したばあいのみ、prog_2が実行されるということができます。その他、Bash等では$?
で直前に実行したコマンドの終了ステータスを取得することができます。
Windowsのバッチでは%ERRORLEVEL%
やIF ERRORLEVEL 1 goto error
といった使い方ができます。
5. パイプとは関係ありますか?
パイプは標準入出力を使った機能で、より多くの情報をプロセス間でやり取りできます。プロセス間の情報のやり取りと言えば同じですが、終了ステータスは子から親への整数値のみと言うかなり限られた物で、使い道も異なります。
6. なぜ、Javaのmain
では戻り値がないんですか?
Javaを含めた現代的言語のほとんどはexit
関数に相当する物で終了ステータス指定するようにしています。そもそも、失敗終了などの異常終了は、プログラムがそれ以上実行出来ない異常事態に陥った場合です。それが発覚するのはmain
関数の中というのはかなり希であり、その場でexit
関数を呼び出すでしょう。つまり、main
関数にそのような機能を付けたとしてもreturn 0;
以外を使うことはほとんどないから、付けなかったと思われます。極少ない例をとっても、main
関数内でexit
関数を呼び出してはいけないわけではありませんので、無くても誰も困らないと判断されたのでしょう。
Cが作られた当初のUNIXは、小さいプログラムをたくさん用意して、それを組み合わせて使うことが多かったというのもあると思います。小さいプログラムにおいて、main
関数の戻り値で終了ステータスを表すというのは有用だったのかも知れません。しかし、現代は、プログラムは複雑高機能化する傾向にあり、時代にそぐわなくなったのだとも思われます。
投稿2020/06/20 04:57
編集2020/06/20 05:05総合スコア21739
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Cのプログラムが稼働する環境としては、
・汎用OSの元で動くホスト環境
・組み込みなどのフリースタンディング環境
の2つが想定されています。int main()
というのはホスト環境の場合です。
この場合は、「何らかのOSから呼び出されるプログラム」なので、一般的なOSの仕様に合わせて返り値がint
になってます。OSはプログラムの実行が終わったら返り値を確認して、その結果で次の処理を変えることがあります。
実際に使える数値の範囲はOSに依存しますので、return 1000;
が期待通り動くかはOSによります。
例えば、Unix/Linuxだと可能な返り値は0
~255
で、それ以外の数値だと数値表現の下位1バイトを符号無し2進数とみなした値になります。
(また、例外で終了した場合は129
以上になるのでそれと区別するためには128
以下にしておく必要があります)
Windowsだと4バイト数値まで返せるようです(詳細未確認)。
可能性としては、OSがプログラムから完了コードとして受け取る値が整数値じゃなく文字列値であるようなOSも作れるでしょうが、そういうOSはCでは想定していません。
投稿2020/06/20 03:40
総合スコア85901
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
もともと、CはUNIXを記述するために作られた言語です。で、UNIXにはパイプと言う機能があって、小さなプログラムを複数繋いで1つの処理をする様に出来ます。また、コマンドを&&で繋ぐ、あるいはシェルで結果を判定してプログラムが処理を全うできなかった(エラー)場合、後続のプログラムを実行しないように、終了ステータス(mainの返す値)を判定して実行の有無をきりわける必要が有ります。
以下参照
C言語のreturn 0の有用性が今更わかった話
投稿2020/06/20 03:33
編集2020/06/20 04:16総合スコア6851
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/20 04:01 編集
2020/06/20 03:46
2020/06/20 03:56
0
なぜCやC++のmainがintを返すのか、を考えるよりも、なぜJavaはmainをvoidにしたのか、を考えるほうがいいかと思います。
結局のところ、Cが最初に言語設計された時代の計算機環境では、mainが(プログラム全体の実行結果として)intの値を返すことが合理的であり、C++は「better C」として書けるという理由からそれを受け継ぎ、後から設計されたJavaは別の理由でvoidを採用したという順番なので。
投稿2020/06/20 03:09
編集2020/06/20 03:10総合スコア11990
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
return 0;
で、呼び出し側に 0が通知されます。
通常、0 はエラー無しを意味します。
今、あまり使われる事は無い(?)ですが、 Windowsでは、Batファイルでその戻り値を見て処理の分岐を行う事ができます。(Unix系もそうだけど、忘れた)
投稿2020/06/20 02:32
総合スコア6385
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/20 03:04
2020/06/20 03:11
2020/06/20 03:13
0
javaは開発者が意図する場所で exit codeを返す必要はないのは
jvmでシステム差異を吸収するためで、コマンド側で結果(例外、エラー、system.exit)によりjavaコマンドのint mainで処理しているため
投稿2020/06/20 08:20
編集2020/06/20 08:24退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
こんなに回答がついているのに誰も書いていないので補足すると、C++ではmain関数のreturn文を省略できます。
basic.start.main/5
A return statement ([stmt.return]) in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument.
If control flows off the end of the compound-statement of main, the effect is equivalent to a return with operand 0 (see also [except.handle]).
投稿2020/06/20 14:22
総合スコア5852
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/20 16:57
2020/06/20 18:01
2020/06/21 00:35
2020/06/21 06:22
2020/06/22 05:01
2020/06/22 05:12
2020/06/22 05:15
2020/06/22 05:21
2020/06/22 09:27
0
Javaはよく知りませんが、(きっとあるだろうと探してみると)System.exit()とかいうメソッドがあって、それがCにおけるmain関数でのreturn引数と同じ効果を持つようですね。
そういうメソッド/関数がわざわざ設けられているということなので「意味はある」ということが想像できるでしょう。バッチファイルやシェルスクリプトを組むとかしないとその恩恵には預かれないので「無意味」と思ってしまうこともあるかも知れませんが、あなたの知らないセカイもあるんだ、ということで。
投稿2020/06/20 03:33
総合スコア7703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。