0

コンパイラは警告を出します warning: second argument of ‘int main(int, std::string*)’ should be ‘char **’ [-Wmain]

入れることを選んだとき

int main(int argv, std::string a[])

それ以外の

int main(int argv, char * argc [])

理由が思いつく場合は、文字列アプローチの何が問題なのかを教えてください。

つまり、 std::string は文字表現/文字列表現のポスターチャイルドであり、 C++ の場合、なぜ C スタイルを気にするのですか?

また

標準実装のハックは本当にありませんか?

4

3 に答える 3

10

理由は非常に単純です。言語規則はフォームを義務付けておらず、使用する実装は独自の選択でそれをサポートしていません。

標準 3.6.1p2 の引用

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

int main() { /* ... */ }

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

後者の形式では、argc は、プログラムが実行される環境からプログラムに渡される引数の数になります。argc がゼロ以外の場合、これらの引数は argv[argc-1] を介して argv[0] に null で終わるマルチバイト文字列 (NTMBS) (17.3.2.1.3.2) の最初の文字へのポインターとして提供され、argv[0] は次のようになります。プログラムまたは "" を呼び出すために使用される名前を表す NTMBS の最初の文字へのポインター。argc の値は非負でなければなりません。argv[argc] の値は 0 でなければなりません。]

編集:追加の質問をカバーするには:

元の argc と argv を取り、文字通りベクトルに処理する関数またはクラスを使用するために停止するものは何もないため、何かを「ハック」する必要はありません。私たちはたくさんのそれらを出回っており、年間に一握り以上の main()-s を作成する人は、おそらくそれらの 1 つまたは独自のものを既に使用しています。

于 2013-06-30T19:14:00.970 に答える
1

実装がそれをサポートする必要がない理由が示されました。ただし、実装がそれをサポートしたくない理由もあります。

(通常はプリコンパイルされた) コード呼び出しmainは、 anintおよび aを渡しますchar**(一部の実装では、拡張子 a second としてchar**; 実際、多くのプラットフォームでは、オペレーティング システムによって既に提供されているデータを正確に取得し、それを渡すだけです)。末尾の引数を無視することをサポートするのは簡単です (通常、それらは逆の順序でスタックにプッシュされるため、追加の引数を無視することは単にそれらにアクセスしないことを意味し、追加のロジックは必要ありません)。char**ただし、単に aを as として読み取ることはできません。std::string*であるため、コンパイラはこのインターフェイスをサポートするために追加のコードを生成する必要があります。そのインターフェイスを使用するソース コードはとにかく移植性がなく、それを使用する人はほとんどいないことを考えると、元のインターフェイスが問題なく機能することを考えると、その代替インターフェイスを実装するのはリソースの浪費にすぎません。

于 2013-06-30T19:50:44.543 に答える