標準C —ホスト環境
ホスト環境(通常の環境)の場合、C11標準(ISO / IEC 9899:2011)は次のように述べています。
5.1.2.2.1プログラムの起動
プログラムの起動時に呼び出される関数の名前はmainです。実装は、この関数のプロトタイプを宣言していません。これは、戻り値の型で定義され、intパラメータはありません。
int main(void) { /* ... */ }
または2つのパラメーター(ここでは、 argc andargvが、宣言されている関数に対してローカルであるため、任意の名前を使用できます):
int main(int argc, char *argv[]) { /* ... */ }
または同等のもの; 10)または他の実装定義の方法で。
それらが宣言されている場合、メイン関数のパラメーターは次の制約に従います。
- の価値
argc負ないものとします。
argv[argc] ヌルポインタでなければならない。
- の値が
argcゼロより大きい場合、配列のメンバーargv[0]は
argv[argc-1]包括的にには、プログラムの起動前にホスト環境によって実装定義の値が与えられている文字列へのポインターが含まれます。その目的は、ホスト環境の他の場所からプログラムを起動する前に決定されたプログラム情報を提供することです。ホスト環境が文字列を大文字と小文字の両方で提供できない場合、実装は文字列が小文字で受信されるようにします。
- の値が
argcゼロより大きい場合、が指す文字列argv[0]
はプログラム名を表します。argv[0][0]ホスト環境からプログラム名を取得できない場合は、ヌル文字になります。の値がargc1より大きい場合、argv[1]throughが指す文字列argv[argc-1]
はプログラムパラメータを表します。
- 配列が指すパラメーター
argcとargv文字列はargv、プログラムによって変更可能であり、プログラムの起動とプログラムの終了の間、最後に格納された値を保持します。
10)したがって、intとして定義されたtypedef名で置き換えることができますint。または、のタイプをargvとして記述することができます
char **argv。
C99またはC11でのプログラムの終了
から返された値はmain()、実装で定義された方法で「環境」に送信されます。
5.1.2.2.3プログラムの終了
1 main関数の戻り型がと互換性のある型である場合、int最初のmain関数呼び出しからのexit戻りは、main関数によって返された値を引数として関数を呼び出すことと同じです。11)関数}を終了するに到達すると
main、値0が返されます。戻りの型がと互換性がない場合int、ホスト環境に返される終了ステータスは指定されていません。
11) 6.2.4に従って、自動ストレージ期間が宣言されたオブジェクトのライフタイムはmain
、前者の場合、後者の場合ではなくても終了します。
これ0は「成功」として義務付けられていることに注意してください。必要に応じてEXIT_FAILURE、EXIT_SUCCESSfrom およびfrom を使用できます<stdlib.h>が、0は十分に確立され、1も確立されます。255より大きい終了コードも参照してください—可能ですか?。
C89では(したがってMicrosoft Cでは)、main()関数が戻ったが戻り値を指定しなかった場合に何が起こるかについての記述はありません。したがって、未定義の動作につながります。
7.22.4.4 exit関数
¶5最後に、制御はホスト環境に戻されます。の値statusがゼロまたはの場合、EXIT_SUCCESSステータスが正常に終了したという、実装で定義された形式が返されます。値がいる場合statusでEXIT_FAILURE、状況の実装定義フォームの失敗終了が返されます。それ以外の場合、返されるステータスは実装定義です。
標準C ++ —ホスト環境
C ++ 11標準(ISO / IEC 14882:2011)は次のように述べています。
3.6.1メイン関数[basic.start.main]
¶1プログラムは、プログラムの指定された開始点であるmainと呼ばれるグローバル関数を含まなければならない。[...]
¶2実装はmain関数を事前定義してはならない。この関数はオーバーロードしないでください。戻り型はint型ですが、それ以外の場合はその型は実装で定義されます。すべての実装は、以下のメインの定義の両方を許可するものとします。
int main() { /* ... */ }
そして
int main(int argc, char* argv[]) { /* ... */ }
後者の形式にargcは、プログラムが実行される環境からプログラムに渡される引数の数が含まれます。argcがゼロ以外の場合、これらの引数はnullで終了するマルチバイト文字列(NTMBS)(17.5.2.1.4.2)の最初の文字へのポインタとしてargv[0]
throughから提供され、使用する名前を表すNTMBSの最初の文字へのポインタになります。プログラムを起動します。の値は負でないものとします。の値は
0です。[注:の後に、さらに(オプションの)パラメータを追加することをお勧めします。—エンドノート]argv[argc-1]argv[0]""argcargv[argc]argv
¶3関数mainはプログラム内で使用してはならない。のリンケージ(3.5)mainは実装定義です。[...]
¶5mainのreturnステートメントは、main関数を終了し(自動保存期間を持つオブジェクトを破棄)std::exit、引数として戻り値を使用して呼び出す効果があります。returnステートメントに遭遇せずに制御がメインの終わりに到達した場合、その効果は実行の結果です。
return 0;
C ++標準では、「[メイン関数]の戻り値の型はtype intでなければならないが、それ以外の場合はその型は実装で定義されている」と明記されており、C標準と同じ2つの署名をオプションとしてサポートする必要があります。したがって、「void main()」はC ++標準では直接許可されていませんが、非標準の実装を停止して代替を許可することはできません。C ++はユーザーによる呼び出しを禁止していることに注意してくださいmain(ただし、C標準では禁止されていません)。
C ++ 11標準には、§7.22.4.4 の段落と同じである§18.5の開始と終了の段落があります。C11 標準のexit関数(上記で引用)は、脚注(これは単に文書化されEXIT_SUCCESS、EXIT_FAILURE定義されている)を除いてで<cstdlib>)。
標準C —共通拡張
古典的に、Unixシステムは3番目のバリアントをサポートします。
int main(int argc, char **argv, char **envp) { ... }
3番目の引数は、nullで終了する文字列へのポインタのリストです。それぞれのポインタは、名前、等号、および値(空の場合もある)を持つ環境変数です。これを使用しない場合でも、 ' extern char **environ;' を介して環境にアクセスできます。このグローバル変数は、それを宣言するヘッダーがないという点でPOSIXの変数の中で一意です。
これは、C規格によって、Annex Jに文書化されている共通の拡張機能として認識されています。
J.5.1環境引数
¶1ホストされた環境では、メイン関数は3番目の引数を受け取ります。この引数はchar *envp[]、nullで終了するへのポインターの配列を指しchar、それぞれがこのプログラムの実行環境に関する情報を提供する文字列を指します(5.1。 2.2.1)。
マイクロソフトC
マイクロソフトVS 2010コンパイラが面白いです。ウェブサイトは言う:
mainの宣言構文は次のとおりです
int main();
または、オプションで
int main(int argc, char *argv[], char *envp[]);
または、mainand wmain関数をvoidreturn(戻り値なし)として宣言することもできます。void を宣言するmainかwmain、またはvoidを返す場合、returnステートメントを使用して親プロセスまたはオペレーティングシステムに終了コードを返すことはできません。mainまたはwmainとして宣言されているときに終了コードを返すにはvoid、exit関数を使用する必要があります。
のプログラムvoid main()が終了したときに何が起こるか(親またはOSにどの終了コードが返されるか)ははっきりしません。また、MS Webサイトもサイレントです。
興味深いことに、MSはmain()、CおよびC ++標準が必要とする2つの引数のバージョンを規定していません。3番目の引数がchar **envp環境変数のリストへのポインタである3つの引数形式のみを規定しています。
Microsoftのページにwmain()は、ワイド文字列など、他の選択肢もいくつかリストされています。
このページのMicrosoft Visual Studio 2005バージョンは、代替としてリストされていません。Microsoft Visual Studio 2008以降のバージョンで対応しています。void main()
標準C —独立型環境
前述のとおり、上記の要件はホスト環境に適用されます。(ホストされた環境の代替となる)独立した環境で作業している場合、標準は言うことはほとんどありません。独立した環境の場合、プログラムの起動時に呼び出される関数を呼び出す必要mainはなく、その戻り値の型に制約はありません。標準は言う:
5.1.2実行環境
自立型とホスト型の2つの実行環境が定義されています。どちらの場合も、指定されたC関数が実行環境によって呼び出されると、プログラムが起動します。静的な保存期間を持つすべてのオブジェクトは、プログラムの起動前に初期化(初期値に設定)されます。そうでなければ、そのような初期化の方法とタイミングは特定されていません。プログラムの終了により、実行環境に制御が戻ります。
5.1.2.1独立型環境
(Cプログラムの実行がオペレーティングシステムの利点なしに行われる可能性がある)独立した環境では、プログラムの起動時に呼び出される関数の名前とタイプは実装定義です。4節で必要とされる最小セット以外の、独立型プログラムで使用可能なライブラリ機能は、実装定義です。
独立した環境でのプログラム終了の影響は、実装によって定義されます。
第4項の適合性への相互参照はこれを参照します。
¶5 厳密に準拠するプログラムは、この国際標準で指定されている言語およびライブラリの機能のみを使用するものとします。3)未指定、未定義、または実装定義の動作に依存する出力を生成せず、最小実装制限を超えてはなりません。
¶6適合する実装の2つの形式は、ホスト型と独立型です。準拠したホストされた実装では、任意の厳密に準拠するプログラムを受け入れるもの。適合自立実装では、ライブラリ句(項7)で指定された機能の使用は、標準ヘッダの内容に限定される任意の厳密に適合するプログラムを受け入れなければならない<float.h>、<iso646.h>、<limits.h>、<stdalign.h>、
<stdarg.h>、<stdbool.h>、<stddef.h>、<stdint.h>、および
<stdnoreturn.h>。厳密に準拠するプログラムの動作を変更しない限り、準拠する実装に拡張機能(追加のライブラリ関数を含む)が含まれる場合があります。4)
¶7 適合プログラムは、適合実装に受け入れられるプログラムです。5)
3)厳密に準拠するプログラムは、条件付き機能(6.10.8.3を参照)を使用できます。ただし、関連するマクロを使用する適切な条件付き包含前処理指令によって使用が保護されている場合に限ります。例えば:
#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
/* ... */
fesetround(FE_UPWARD);
/* ... */
#endif
4)これは、準拠する実装が、この国際標準で明示的に予約されている識別子以外の識別子を予約しないことを意味します。
5)厳密に準拠するプログラムは、準拠する実装間で最大限に移植できるように意図されています。適合プログラムは、適合実装の非移植機能に依存する場合があります。
機能を実際に定義する独立した環境に必要なヘッダーは唯一であることに注意してください<stdarg.h>(さらに、それらはマクロである場合もあり、多くの場合は単なるマクロです)。
標準C ++ —独立型環境
C標準がホスト環境と独立環境の両方を認識するように、C ++標準も同様です。(ISO / IEC 14882:2011からの引用)
1.4実装コンプライアンス[intro.compliance]
¶72種類の実装が定義されています:ホストされた実装と独立した実装です。ホストされた実装の場合、この国際標準は利用可能なライブラリのセットを定義します。独立した実装とは、オペレーティングシステムの利点なしに実行が行われる可能性がある実装であり、特定の言語サポートライブラリ(17.6.1.3)を含む実装定義のライブラリセットがあります。
¶8適合した実装は、整形式プログラムの動作を変更しない限り、拡張機能(追加のライブラリ関数を含む)を持つ場合があります。この国際標準に従って不適切な形式の拡張機能を使用するプログラムを診断するには、実装が必要です。ただし、そうすることで、そのようなプログラムをコンパイルして実行できます。
¶9各実装は、それがサポートしないすべての条件付きでサポートされる構成を識別し、すべてのロケール固有の特性を定義するドキュメントを含むものとします。3
3)このドキュメントは、実装定義の動作も定義しています。1.9を参照してください。
17.6.1.3独立型の実装[コンプライアンス]
ホスト型と独立型の実装の2種類が定義されています(1.4)。ホストされた実装の場合、この国際標準は利用可能なヘッダーのセットを記述します。
独立した実装には、実装で定義された一連のヘッダーがあります。このセットには、少なくとも表16に示すヘッダーが含まれます。
ヘッダの供給されたバージョンは、<cstdlib>少なくとも関数を宣言しなければならないabort、atexit、at_quick_exit、exit、およびquick_exit(18.5)。この表にリストされている他のヘッダーは、ホストされる実装の場合と同じ要件を満たしている必要があります。
表16 —独立型実装のC ++ヘッダー
Subclause Header(s)
<ciso646>
18.2 Types <cstddef>
18.3 Implementation properties <cfloat> <limits> <climits>
18.4 Integer types <cstdint>
18.5 Start and termination <cstdlib>
18.6 Dynamic memory management <new>
18.7 Type identification <typeinfo>
18.8 Exception handling <exception>
18.9 Initializer lists <initializer_list>
18.10 Other runtime support <cstdalign> <cstdarg> <cstdbool>
20.9 Type traits <type_traits>
29 Atomics <atomic>
int main()Cでの使用についてはどうですか?
C11標準の標準§5.1.2.2.1は推奨される表記法を示しています— int main(void)—しかし、標準には次の2つの例がありますint main():§6.5.3.4¶8と§6.7.6.3¶20。ここで、例は「規範的」ではないことに注意することが重要です。これらは単なる例示です。例にバグがあっても、標準の本文には直接影響しません。とは言っても、それらは予想される動作を強く示しているため、標準にint main()例が含まれている場合、それがint main()推奨される表記法でなくても禁止されていないことを示唆しています。
6.5.3.4 sizeofand _Alignof演算子
…
¶8例3この例では、可変長配列のサイズが計算され、関数から返されます。
#include <stddef.h>
size_t fsize3(int n)
{
char b[n+3]; // variable length array
return sizeof b; // execution time sizeof
}
int main()
{
size_t size;
size = fsize3(10); // fsize3 returns 13
return 0;
}