C++における return 0; の役割と必要性

未分類

C++で一番最初に書くプログラムといえば次のようなものです。

#include <bits/stdc++.h>
using namespace std;

int main() {
    cout << "Hello, world!\n";
    return 0;
}

この最後の return 0;、みんななんとなく書いていますが、「なぜ要るのか」「なくても動くのになぜ書くのか」をはっきり説明できる人は案外少ないと思います。この記事では公式ドキュメントや標準に沿って整理します。

1. C++標準は main の戻り値をどう書けと言っているか

C++ のアーリードラフト(N3337, C++11 時点)にははっきりこう書かれています。

“This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined.”

mainint を返す型でなければならない。それ以外の細かいところ(引数の取り方など)は処理系が決めてよい。その代わり処理系はどう決めたかを文書にしておくこと。

「implementation-defined」はこういう意味です。

  • 標準が『ここは処理系に任せる』と決めている部分のこと。
  • ただし 好き勝手にしていいのではなく、その処理系(コンパイラやライブラリ)がどうするかを文書に書いて公開しなければならない、という義務つきです。

mainint を返す関数として書きなさい、というのが公式のルールです。なので正しい形は次のどちらかです。

int main() {
    // ...
    return 0;
}

// または
int main(int argc, char* argv[]) {
    // ...
    return 0;
}

2. 「書かなくても 0 を返す」は main にだけ許された特別ルール

cppreferenceのMain functionの節にはこうあります。

 The body of the main function does not need to contain the return statement: if control reaches the end of main without encountering a return statement, the effect is that of executing return 0;.

Main function - cppreference.com

ポイントは2つです。

  1. main の末尾まで来たら、自動的に return 0; したことにする
  2. これは main にだけ 付いている特別ルールで、ほかの「戻り値あり」関数ではやってくれない

Flowing off the end of a value-returning function, except the main function and specific coroutines(since C++20), without a return statement is undefined behavior.

return statement - cppreference.com

なので、次のコードは標準上はOKです。

int main() {
    // do something
}   // ←ここで暗黙に return 0;

でも、同じことを他の関数でやると未定義の動作となります。

3. return 0; の役割 ― OSへの正常な終了の報告

main が返した整数は、そのままプロセスの終了コードとして OS に渡されます。cppreference (C 版の main の項) もこう書いています。

If the return statement is used, the return value is used as the argument to the implicit call to exit() (see below for details). The values zero and EXIT_SUCCESS indicate successful termination, the value EXIT_FAILURE indicates unsuccessful termination.

つまり return 0; は「問題なく終わりました」という合図です。逆に 0 以外を返せば「何かあった」と呼び出し元(シェルや親プロセス)に伝えられます。

4. それでも明示して書くべき理由

「じゃあ書かなくても 0 なんでしょ」で終わらせないほうがいい理由は3つあります。

  1. 意図が見えるから
    末尾に return 0; があれば、「このプログラムはここで正常終了させるつもりだ」と誰が読んでも分かります。
  2. 他言語・他環境に揃えやすいから
    C でも同趣旨の規定がありますが、古い処理系や厳しい設定だと警告が出ることがあります。書いておけば静かです。
  3. 初心者に教えるときに一貫するから
    標準が「int を返せ」と言っている以上、「int main と書いて最後に return 0;」という一番まっすぐな形で覚えさせるのが親切です。

5. よくある誤り:void main() など

標準の文言は「It shall have a return type of type int」なので、void main() は標準外です。コンパイラが受け付けることはありますが、それは処理系拡張です。標準に沿いたいなら使わないほうがいいです。

コメント

タイトルとURLをコピーしました