web-dev-qa-db-ja.com

main()はC ++でオーバーロードされていますか?

main()の2つの有効なバージョンがC++に存在します。

int main()  // version 1
int main(int argc, char **argv)  // version 2

ただし、両方の過負荷を同時に共存させることはできません。何故なの? (潜在的な使用例:端末からプログラムを実行しているときに、引数が渡されない場合は最初のバージョンが呼び出され、それ以外の場合は2番目のバージョンが呼び出されます。)

コンパイラは、バイナリごとに1つのバージョンのみを許可する特別なチェックを実行しますか?

67
iammilind

§3.6.1/ 2(C++ 03)は言う

実装は、main関数を事前定義してはなりません。 この関数はオーバーロードされません。戻り値の型はint型でなければなりませんが、それ以外の場合、その型は実装定義です。すべての実装では、次のmainの定義の両方を許可する必要があります。

   int main() { /* ... */ }
   int main(int argc, char* argv[]) { /* ... */ }

どちらでも使用できます。どちらも標準に準拠しています。

また、char *argv[]char **argvと同等であるため、char *argv[]char **argvに置き換えても違いはありません。


ただし、両方のバージョンを同時に共存させることはできません。 (ユースケースは次のようになります:コマンドプロンプトからバイナリを実行しているときに、引数を渡さない場合は、最初のバージョンを呼び出す必要があります。それ以外の場合は、2番目のバージョンを呼び出す必要があります)。

いいえ。両方のバージョンを同時に共存させることはできません。 1つのプログラムに1つのmain関数を含めることができます。どちらを選択するかによって異なります。コマンドライン引数を処理する場合は、2番目のバージョンを選択する必要があります。そうでない場合は、最初のバージョンで十分です。また、2番目のバージョンを使用し、コマンドライン引数を渡さない場合は、害がないことにも注意してください。エラーは発生しません。それに応じてargcargvを解釈する必要があり、それらの値に基づいて、プログラムのロジックとフローを作成する必要があります。

65
Nawaz

WindowsとUnixには次のものがあります。

int main(int argc, char **argv, char **envp)

およびWin32アプリには次のものがあります。

int WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);

macOSには次のものがあります。

int main(int argc, char **argv, char **envp, char **Apple)

mainは通常、プログラムの実行時にOSが最初に呼び出すものではないことを忘れないでください。 main関数は、ランタイム環境によって呼び出される関数です。実行する最初の命令のアドレスは、通常、一部のメタデータで宣言されます。通常、実行可能ファイルの場合は開始時に宣言されます。

上記のいずれも、私が知る限り、C/C++標準と矛盾するものはありません。ただし、1つしかない場合は、OSが複数ある場合にどちらを呼び出すかわからないため、これは理にかなっています。 1つしかないことの確認は、コンパイラでは行われず、リンカで行われます。

20
Skizz

セクション3.6.1.2 C++ Standard 1998および2003エディションの両方の状態:

実装は、主な機能を事前に定義してはなりません。 この関数はオーバーロードされません。戻り値の型はint型でなければなりませんが、それ以外の場合、その型は実装定義です。

さらに、

ISO C++標準(ISO/IEC 14882:1998)は、特にmainがintを返すことを要求しています。これには、整形式のプログラムに対する明示的な「shall」制約があります。

セクション§3.6.1¶2:

戻り値の型はintですが、それ以外の場合、その型は実装定義です。すべての実装では、次のmainの定義の両方を許可する必要があります。

int main() { /* … */ }

そして

int main(int argc, char* argv[]) { /* … */ }

したがって、mainの両方のバージョンが標準で許可されており、どちらを使用するかはプログラマーの実装設定として残されています。

13
Alok Save

メインはC時代に定義されました。これは、printfのルールに沿って設定されています。 mainを可変個引数関数と見なします。

int main(...)

標準では、引数なしと2つのポインタ引数で問題ないとされています。ただし、実装がより多くの引数を提供したい場合、実装は自由にそうすることができます。

2つのmainsを持つことができない理由は、Cプログラムでprintfのような関数を2回定義できないのと同じ理由です。確かに、printfは異なる引数をサポートし、そこにある引数に応じて動作を変更しますが、C++という用語の意味で過負荷ではありません。

9
Billy ONeal

標準では、mainはオーバーロードできないとされています。マングルされておらず、同じアンマングル名で2つの関数を持つことはできません。これによりリンクエラーが発生すると思いますが、コンパイラーは、より明確なエラーメッセージを表示するために、明示的なチェックを追加することができます。

int main(int argc, char **argv)int main()を優先署名にする必要がありますが、コンパイラーはさまざまなパラメーターを使用してmainを自由に受け入れることができます。

7
peoro

C++でmain()をオーバーロードすることはできません。コンパイラは次のエラーを示しました。

error C2731: 'main' : function cannot be overloaded 
0
Dheeraj Bansal