main関数
プログラムには main という名前のグローバル関数を含まなければならず、それはホスト環境におけるプログラムの指定された開始点です。それは、以下のいずれかの形式を持たなければなりません。
int main() { 本体 } |
(1) | ||||||||
int main(int argc, char* argv[]) { 本体 } |
(2) | ||||||||
int main(/* 実装定義 */) { 本体 } |
(3) | ||||||||
main 関数。main 関数。main 関数。main 関数では、追加の(オプションの)引数を argv の後に置くことを推奨しています。| argc | - | プログラムが実行される環境からプログラムに渡される引数の数を表す非負の値。 |
| argv | - | argc + 1 個のポインタからなる配列の最初の要素へのポインタ。その最後のポインタはヌルであり、それ以前のポインタ(もしあれば)は、実行環境からプログラムに渡された引数を表すヌル終端マルチバイト文字列を指します。argv[0] がヌルポインタでない場合(または、同等に argc > 0 の場合)、それはプログラムを呼び出すために使用された名前を表す文字列、または空文字列を指します。 |
| 本体 (body) | - | main 関数の本体。 |
目次 |
[編集] 説明
main 関数は、静的記憶域期間を持つ非ローカルオブジェクトの初期化の後、プログラムの開始時に呼び出されます。これは、ホスト環境(つまり、オペレーティングシステムがある環境)で実行されるプログラムへの指定されたエントリーポイントです。フリースタンディングプログラム(ブートローダー、OSカーネルなど)へのエントリーポイントは実装定義です。
main 関数の2引数形式の引数により、実行環境から任意のマルチバイト文字列を渡すことができます(これらは一般的にコマンドライン引数として知られています)。ポインタ [argv[1], argv[argc - 1]] は、これらの各文字列の最初の文字を指します。argv[0] は(ヌルでなければ)プログラム自体を呼び出すために使用された名前を表すヌル終端マルチバイト文字列の最初の文字へのポインタです(または、実行環境でこれがサポートされていない場合は空文字列 "")。文字列は変更可能ですが、これらの変更は実行環境には反映されません。例えば、std::strtok で使用することができます。argv が指す配列のサイズは少なくとも argc + 1 であり、最後の要素 argv[argc] はヌルポインタであることが保証されます。
main 関数には、以下のようないくつかの特別な性質があります。
main 関数の本体には return 文を含める必要はありません。return文に遭遇することなく main の終わりに制御が達した場合、その効果は return 0; を実行するのと同じです。main の終わりに達したときの暗黙のreturn)は、まず通常通り関数を抜けること(これにより、自動記憶域期間を持つオブジェクトが破棄され、main の事後条件アサーションが評価されます(C++26以降))、次に return の引数と同じ引数で std::exit を呼び出すことと等価です(その後 std::exit は静的オブジェクトを破棄し、プログラムを終了します)。main 関数にはいくつかの制限があります(これに違反するとプログラムは不適格となります)。
main という名前は関数用に予約されています(ただし、クラス、名前空間、列挙型、および非グローバル名前空間内の任意のエンティティに名前を付けるために使用できますが、main という名前のエンティティを任意の名前空間でC言語リンケージで宣言することはできません)。constexpr(C++11以降)、consteval(C++20以降)、inline、またはstaticで宣言したりすることはできません。|
4) main 関数の戻り値の型は推論できません(auto main() {...} は許可されません)。 |
(C++14以降) |
| (C++20以降) |
[編集] 注意
main 関数が関数 try ブロックで定義されている場合、静的オブジェクトのデストラクタ(暗黙の std::exit によって破棄される)によってスローされた例外は、それによって捕捉されません。
OSのコマンドラインで与えられた引数が argv によって参照されるマルチバイト文字配列に変換される方法は、実装定義の処理を含む場合があります。
- C++ コマンドライン引数の解析 MSDN
- シェル入門 POSIX
非常によくある実装定義の main() の形式は、(argc と argv に加えて)3番目の引数を持ち、その型は char** で、実行環境変数を指すポインタの配列を指します。
[編集] 例
プログラムに入力を見つける場所と結果を書き込む場所を通知する方法を示します。
考えられる呼び出し方: ./convert table_in.dat table_out.dat
#include <cstdlib> #include <iomanip> #include <iostream> int main(int argc, char *argv[]) { std::cout << "argc == " << argc << '\n'; for (int ndx{}; ndx != argc; ++ndx) std::cout << "argv[" << ndx << "] == " << std::quoted(argv[ndx]) << '\n'; std::cout << "argv[" << argc << "] == " << static_cast<void*>(argv[argc]) << '\n'; /* ... */ return argc == 3 ? EXIT_SUCCESS : EXIT_FAILURE; // optional return value }
実行結果の例
argc == 3 argv[0] == "./convert" argv[1] == "table_in.dat" argv[2] == "table_out.dat" argv[3] == 0
[編集] 参照
| 拡張コンテンツ |
|---|
|
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 1003 | C++98 | サポートされる main の引数名が過度に制限されていた |
すべての有効な引数名が サポートされる |
| CWG 1886 | C++98 | main 関数は言語リンケージで宣言できた |
禁止された |
| CWG 2479 | C++20 | main 関数は consteval で宣言できた |
禁止された |
| 禁止された | C++98 | CWG 2811 | N3214以降、main 関数が使用されているかどうかが不明確だった |
[編集] 関連項目
main 関数 の C言語ドキュメント |