45

C ++標準では再帰が禁止されていると読みましたmain()が、g++は文句なしに次のコードをコンパイルします。

int main()
{
    main();
}

誰かがこれを明確にすることができますか?

4

5 に答える 5

49

3.6.1 / 3の標準によると、そうではありません。

プログラム内でこの関数main を使用してはならない (3.2)

使用されるの定義:

オブジェクトまたはオーバーロードされていない関数は、その名前が評価される可能性のある式に含まれている場合に使用されます。

于 2010-12-23T12:11:22.113 に答える
37

私は魚をやって、なぜこれが冗長であるかを説明します。CまたはC++プログラムの実行を開始する前に、まずCRTを初期化する必要があります。stdin / out / errを開き、初期化子を呼び出します。これを実現するための2つの基本的な戦略があります。それは、プラットフォームの実装の詳細です。

  • プログラムの開始アドレスは、最終的にmain()を呼び出すCRTinit関数を指します。実行可能イメージの任意のセクションをサポートできるファンシーローダーを備えたフル機能のオペレーティングシステムで一般的です。

  • コンパイラは、CRT初期化関数を呼び出すmain()関数にコードを挿入します。start関数は常にmain()です。ローダー機能が制限されている組み込みプラットフォームで一般的です。main()の繰り返しが問題になり、CRT起動コードが予測できないスタック状態で再度呼び出されます。

于 2010-12-23T14:01:35.823 に答える
22

ここでの主張は、それが実際に特に禁止されているということです。

さて、標準は次のように述べています。

3.6.1.3
「関数mainはプログラム内で使用してはならない。」

5.2.2.9
「mainという名前の関数を除いて、再帰呼び出しは許可されます」

もちろん、これを行うことができます:

int main(int argc, char* argv[]) {
    return foo(argc, argv);
}
int foo(int argc, char* argv[]) {
    if (some_condition) {
        return foo(argc, argv);
    }
    return 0;
}

(get-out句を追加したことに注意してください。仮想的に無限再帰をコーディングすることさえできません。それは私に繰り返されます。)

于 2010-12-23T12:13:39.440 に答える
9

それは合法ではありません。3.6.1-3を読む:

関数mainは、プログラム内で使用してはなりません(3.2)。mainのリンケージ(3.5)は実装定義です。mainがインラインまたは静的であると宣言するプログラムは形式が正しくありません。mainという名前は他に予約されていません。[例:他の名前空間のエンティティと同様に、メンバー関数、クラス、および列挙をmainと呼ぶことができます。]

于 2010-12-23T12:14:16.583 に答える
1

他の人々は標準の部分に取り組んでいます。-pedantic-errorsただし、これらのエラーの少なくとも1つ(main署名に応じて)を使用すると、g ++(少なくとも4.6.2)はこれを拒否することに注意してください。

error: ISO C++ forbids calling ‘::main’ from within program [-pedantic]
error: ISO C++ forbids taking address of function ‘::main’ [-pedantic]
于 2012-03-04T12:36:35.073 に答える