関数定義のパラメーターの最小数がゼロであることは知っていますが、関数定義のパラメーターの最大数はいくつですか?私は知識のために、そして好奇心から質問をしているのであって、実際の関数を書くつもりではありません。
4 に答える
はい、実装によって課せられる制限があります。あなたの答えは、C++標準からの次の抜粋の太字のテキストで示されています。
1.C++言語
付録B-実施量
コンピューターは有限であるため、C ++の実装では、正常に処理できるプログラムのサイズが必然的に制限されます。すべての実装は、既知の場合、それらの制限を文書化する必要があります。このドキュメントでは、固定制限が存在する場合、利用可能なリソースの関数として変数制限を計算する方法、または固定制限が存在しないか不明であると述べている場合があります。
制限により、以下に説明するものなどを含む数量が制限される場合があります。各数量に続く括弧内の数字は、その数量の最小値として推奨されます。ただし、これらの数量は単なるガイドラインであり、コンプライアンスを決定するものではありません。
—複合ステートメント、反復制御構造、および選択制御構造のネストレベル[256]。
—条件付き包含のネストレベル[256]。
—宣言内の算術、構造、和集合、または不完全な型を変更するポインター、配列、および関数の宣言子(任意の組み合わせ)[256]。
—完全な式内の括弧で囲まれた式のネストレベル[256]。
—内部識別子またはマクロ名の文字数[1024]。
—外部識別子の文字数[1024]。
—1つの変換ユニット内の外部識別子[65536]。
—1つのブロックで宣言されたブロックスコープを持つ識別子[1024]。
—1つの変換ユニットで同時に定義されたマクロ識別子[65536]。
—1つの関数定義のパラメーター[256]。
—1つの関数呼び出しの引数[256]。
—1つのマクロ定義のパラメーター[256]。
—1つのマクロ呼び出しでの引数[256]。
—1つの論理ソース行の文字[65536]。
—文字列リテラルまたはワイド文字列リテラル(連結後)の文字[65536]。
—オブジェクトのサイズ[262144]。
—#includeファイルのネストレベル[256]。
— switchステートメントのケースラベル(ネストされたswitchステートメントのケースラベルを除く)[16384]。
—単一のクラス、構造、またはユニオンのデータメンバー[16384]。
—単一の列挙型の列挙型定数[4096]。
—単一のstruct-declaration-list [256]内のネストされたクラス、構造体、または共用体定義のレベル。
— atexit()[32]によって登録された関数。
—直接および間接の基本クラス[16384]。
—単一クラスの直接基本クラス[1024]。
—単一のクラスで宣言されたメンバー[4096]。
—アクセス可能かどうかに関係なく、クラス内の仮想関数を最終的にオーバーライドします[16384]。
—クラスの直接および間接の仮想ベース[1024]。
—クラスの静的メンバー[1024]。
—クラス[4096]でのフレンド宣言。
—クラス[4096]のアクセス制御宣言。
—コンストラクター定義のメンバー初期化子[6144]。
—1つの識別子のスコープ資格[256]。
—ネストされた外部仕様[1024]。
—テンプレート宣言のテンプレート引数[1024]。
—再帰的にネストされたテンプレートのインスタンス化[17]。
—tryブロックごとのハンドラー[256]。
—単一の関数宣言で仕様をスローします[256]。
その上、それはまた$ 18.3 /6で言います、
実装の制限:実装は、少なくとも32の機能の登録をサポートする必要があります。
2.C言語
5.2.4.1翻訳の制限
実装は、次の制限のすべての少なくとも1つのインスタンスを含む少なくとも1つのプログラムを変換および実行 できる必要があります
。— 127のネストレベルのブロック
— 63のネストレベルの条件付き包含
— 12のポインター、配列、および関数宣言子(任意の組み合わせで)宣言内の算術、構造、和集合、または不完全な型の変更
—完全な宣言子内の括弧で囲まれた宣言子の
63のネストレベル—完全な式内の括弧で囲まれた式の63のネストレベル
—内部識別子またはマクロ名の63個の重要な初期文字(各ユニバーサル文字名または拡張ソース文字は単一文字と見なされます)
—外部識別子の31個の重要な初期文字(
0000FFFF以下の短い識別子を指定する各ユニバーサル文字名)は6文字と見なされ、00010000以上の短い識別子を指定する各ユニバーサル文字名は10文字と見なされ、各拡張ソース文字は、対応するユニバーサル文字名と同じ文字数と見なされます)—1つの
4095外部識別子変換ユニット
— 1つのブロックで宣言されたブロックスコープを持つ511の識別子
—1つの前処理変換ユニットで同時に定義された4095のマクロ識別子
— 1つの関数定義に127個のパラメーター—
1つの関数呼び出しに
127個のパラメーター— 1つのマクロ定義に127個のパラメーター—
1つのマクロ呼び出しに127個の引数
—論理ソース行に
4095文字—文字列リテラルまたはワイド文字列リテラル(後連結)
—オブジェクト内の65535バイト(ホスト環境のみ)
— #includedファイルの15のネストレベル
— switchステートメントの1023ケースラベル(ネストされたswitchステートメントのケースラベルを除く)
—単一の構造または共用体の1023メンバー
—単一の列挙内の1023個の列挙定数
—単一のstruct-declaration-list内のネストされた構造または共用体定義の63レベル
ただし、メモには次のように書かれています。
13)実装では、可能な限り、固定の翻訳制限を課すことを避ける必要があります。
以前の回答者が十分に指摘しているように、パラメーターの数はC++コンパイラーによって異なります。コンパイラの制限は、ハードウェア環境によって課せられた制限が原因である可能性があります。
たとえば、VAX CPUアーキテクチャは、引数の数を保持する8ビットフィールドを使用するため、準拠するVAXコードは255を超えるパラメータを渡すことはできません。
同様に、Intel 8048ファミリのような多くの小さなプロセッサはメモリに非常に制約があるため、4つ以上のパラメータを使用するとほとんどのCおよびC++コンパイラが悲しみを覚えます。多くの主流の開発者は8048を嘲笑するかもしれませんが、その子孫は依然として最も広く展開されているCPUの1つであり、主に組み込みデバイスに搭載されています。
多くのRISCアーキテクチャの実装では、スタックではなくレジスタを使用してパラメータを渡す方法を指定しています。たとえば、基本的なARMCPUには16個のレジスタしかありません。パラメータの最大数は、パラメータを渡すコードの生成方法に影響を与えるコンパイラのコマンドラインオプションに大きく依存する可能性があります。たぶん8つ以上がスタックにプッシュされます。そうでないかもしれない。
これらの例が過度に制限されているように思われる場合は、Palm OSがC関数を単一のパラメーターに制限しており、それはタイプint
またはである必要があると考えてくださいvoid *
。
もちろん、このように多数の引数を使用してCで関数を記述している場合は、プログラムの設計を再考する必要があります。