2009-10-25 3 views
24

標準では、mainに2つの有効な(つまり動作保証された)署名が明示されています。すなわち:C++のmainのシグネチャの引数にunsigedとconstの修飾子を付けることはできますか?

int main(); 
int main(int, char*[]); 

私の質問は以下のようなものですか?

int main(const unsigned int, const char* const* argv); 

私のテストでは、「はい」と言うが、私はunsigned intintなどのargvの非トップレベルconst -nessを変更することにより、mainに過負荷をかけるわけではないので、私は答えがわからないんですか?私なら、それは明らかに禁止されています。

したがって、これらの変更は標準準拠のコンパイラで動作することが保証されていますか?

+7

なぜあなたはそのようなことをしたいですか?標準準拠のコード – Glen

+10

Glenを書いて、適合コードを書いてください。だからこそ私はこの質問に最初に尋ねました。 – bh9042

+9

次に、 'int main(int、char **)'を宣言し、あなたのところに来てください。 –

答えて

33

C++ 98標準では、セクション3.6.1に段落2

実装が主な機能をあらかじめ定義してはならないと言います。この関数はオーバーロードしてはならない。返される型はintでなければなりません。それ以外の型は実装定義です。すべての実装はmainの次の定義の両方を許可しなければならない。int main()int main(int argc, char* argv[])

だから、mainを受け入れるENVが許容されるが、それは許されることを標準で義務付けられていません。


これは、多くの場合、ここで彼らの行動を文書以外のものから、自立環境を免除する前の段落であるために呼ばれているので:

プログラムは、指定された開始され、メインと呼ばれるグローバル関数を、含まなければなりませんプログラムの の実装が定義されています フリー機能を定義するために自立環境のプログラムが必要かどうか。[注:独立した環境では、スタートアップ が起動し、実装が定義されています。 スタートアップ には、静的ストレージ期間を持つ名前空間スコープのオブジェクトのコンストラクタの実行が含まれています。終了 には、静的記憶期間を持つオブジェクトのデストラクタの実行が含まれています。 ]

+0

ああ、私はそれを読むときに "タイプ"の部分を見逃しました。 – bh9042

1

標準を読んでわかる限り、あなたは標準に準拠していません。しかし、私はあなたがこれをすることができないコンパイラを想像することはできません。 inと同様に、ほとんど無害で非常にわかりにくいエッジケースを特に禁止するために、コンパイラからもっと多くの作業が必要になります。

+0

アーメン。あなたのコードは、標準に従う100%の仮説的コンパイラでコンパイルすることができます。しかし、ほとんどのコンパイラはそうではありません。このエッジケースは、おそらく技術的に不正な行為を許しているかもしれません。 – DVK

2

ポインタがconst char* constであるべきではありません。プログラムがバッファを変更できるためです。

+0

**文字列へのポインタではなく**文字列のみ。 –

+3

それがポイントです。私は何も変えたくない! – bh9042

+2

次に何も変更しないでください。 –

0

標準によって違法かもしれませんが、ほとんどのランタイムは本当に気にしません。彼らはargcの整数とargvのポインタを押します。mainと呼んで、正しく解析することを願ってください。したがって、あなたの所見では、 "作業保証"は議論の余地があります。なぜなら、ローダーはあなたが議論を宣言したものを本当に気にしないからです。

ビルドすると、mainが呼び出されます。あなたが議論をどのように解析するかはあなた次第です。私は、プラットフォーム全体に固有のものであることを明確にすべきです。

つまり、とは何ですか?

+1

1. argcは非負であることが保証されています。私はそこに署名のないどこかを見たいと思っています...;)2.私はconstが愚かな間違いに対して提供する特別な安全ネットを望みます。 jeffamaphoneに返答したように、私はargvを変更することが許されていますが、私は欲しくない、あるいは必要としません。 – bh9042

+1

'main'はC++に先行し、' unsigned'の時刻までです。あなたが望むものにかかわらず、 'main'はこのように長い間宣言されています。あなたは本当に 'argv'を変更することからあなたを守るためにコンパイラが必要ですか?もしあなたが 'const'を持っていなければ、間違って' - 'を 'argv'文字列の'/'に置き換えようとしていますか?なぜこれが必要なのか私を売っているわけではありません。 –

+1

私は、プログラマが 'unsigned'や' const'のような修飾子を使って仮定や制約を指定できるようにするのが有効なポイントだと思います。ユーザ定義の関数がうまくいけば、 'main()'でもそれがうまくいかない理由は分かりません。 –

19

標準に準拠するには、いずれかの標準準拠の署名を使用する必要があります。

私は自分のやり方を完全に理解しています。最も良い方法は、独自の関数をmyMain()などで作成し、必要な署名を含めてmain()から呼び出すことです。

+5

他の人の代わりに役に立つ回答を提供するための+1「なぜあなたがこれをするのかわかりません」 –

1

コンパイラがmainの名前のマングリングを使用する場合、これは機能しません。結局のところ、C++の機能です。したがって、リンカは2つの特定の "manglings"を探します。あなたの定義には別の名前があります。

mainは特別です(過負荷ではなく、呼び出し可能ではありません)。ネームマングリングはまったく必要ない場合があります。

0

ISO/IEC 9899:TC3

セクション5.1.2.2.1プログラムの起動

プログラムの起動時に呼び出される関数がメインという名前です。実装では、この関数のプロトタイプは と宣言していません。任意の名前が を使用してもよい彼らはに対してローカルであるとして、

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

または二つのパラメータ(argcとargvのようここでいう、と:それはint型の戻り値の型をなし パラメータで定義されなければなりませんそれらが宣言されている機能):

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

またはそれに相当するもの9)または他の実装定義の方法。

関連する問題