[Bash / C 言語] main 関数の “return 0;” の意味

こんにちは。先日、久々に大学時代の友人と会って、十三の餃子酒場で晩御飯を食べに行った k-so16 です。楽しく美味しい時間を過ごせて非常に満足でした。

C 言語を勉強する際に、序盤で main 関数の最後は return 0; という約束事を学ぶと思います。しかし、なぜ main 関数は return 0; で終了するように記述するのかまでは、解説されていないのではないかと思います。

本記事では、 main 関数に return 0; を書く理由について解説します。

本記事の想定読者は以下の通りです。

  • C 言語の基礎的な文法について知っている
  • UNIX シェルの基礎的な知識を有している

シェルの終了ステータスと return 0;

Bash や Zsh などのUNIX シェルは、コマンド実行終了時に、そのコマンドの実行が成功したかなどのステータスの情報を保持しています。この情報を終了ステータスと呼びます。終了ステータスは 0 から 255 までの値が利用されます。

一般に、コマンドが正常終了した場合、シェルのステータスには 0 が保持されます。終了ステータスが 0 以外の場合は、コマンドの実行結果が偽の場合や、コマンドの異常終了を示します。例えば、 grep コマンドの場合、 man page を参照すると、ステータスコードが 0 なら検索文字列が見つかったことを、 1 の場合は見つからなかったことをそれぞれ示し、それ以外の値はエラーが発生したことを示します。

C 言語の main 関数で return 0; を最後に書くことで、プログラムが正常に終了したことをシェルに伝えます。よって、 main 関数内でエラー処理をする場合、エラー処理に return 1; などの非 0 の値を返すようにすれば、プログラムが異常終了したことをシェルに伝えることもできます。標準ライブラリ関数 exit() を使って、 exit(1); と記述する場合も、シェルにプログラムの終了ステータスが 1 であることを伝えます。

シェルの特殊変数 $?

コマンドの終了ステータスの値は特殊変数 $? に格納されます。UNIX シェルにおいて、 $? の値が 0 の場合は真、それ以外の値は偽として扱われます。 $? の値は、シェルスクリプトの if 文や while 文などの条件の真偽に利用されます。

C 言語のプログラムで、 main 関数が return 0; で終了するプログラムを実行した直後では、 $? の値には 0 が入ります。代わりに return 1; でプログラムを終了させれば、 $? には 1 が入ります。

C 言語で作成したプログラムの実行後に実行するコマンド列を、プログラムの正常終了時とそうでない場合で分けたい場合、以下のように記述できます。

if ./a.out
then
  echo "Success"
else
  echo "Failure"
fi

動作は次のようになります。

  1. C 言語のプログラム (./a.out)1 を実行
  2. ./a.out の終了ステータスを評価
    • $? が 0 なら 真、それ以外は偽
  3. 評価結果が真なら then 節を、それ以外は else 節を実行

総括

本記事のまとめは以下の通りです。

  • main 関数の return 0; はシェルにプログラムの正常終了を伝える
  • 終了ステータスによって、条件分岐などのスクリプトも記述できる

以上、 k-so16 でした。 C 言語と UNIX シェルの関係は奥が深いので面白いですね。


  1. ClangGCC などのコンパイラでは、出力ファイル名を指定しなければ、a.out というファイル名でコンパイル実行時のカレントディレクトリに実行ファイルが保存される。 

SNSでもご購読できます。