27

The standard explicitly states that main has two valid (i.e., guaranteed to work) signatures; namely:

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

My question is simple, would something like the following be legal?

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

My tests say 'yes', but I'm unsure of the answer because am I not overloading main by changing int to unsigned int as well as the non top-level const-ness of argv? If I am, then that's clearly prohibited.

So, are these modifications guaranteed to work on a standards conforming compiler?

4

7 に答える 7

33

C++98 標準は、セクション 3.6.1 パラグラフ 2 で述べています

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

mainしたがって、 env の受け入れが許容されることは標準では義務付けられていませんが、許容されます。


これは頻繁に参照されるため、独立した環境をその動作を文書化すること以外から除外する前の段落を次に示します。

プログラムには、プログラムの指定された開始である main と呼ばれるグローバル関数が含まれます。独立した環境のプログラムがメイン関数を定義する必要があるかどうかは、実装によって定義されます。[注: 独立した環境では、起動と終了は実装定義です。startup には、静的ストレージ期間を持つ名前空間スコープのオブジェクトのコンストラクターの実行が含まれます。終了には、静的ストレージ期間を持つオブジェクトのデストラクタの実行が含まれます。]

于 2009-10-25T18:36:57.223 に答える
20

標準に準拠するには、標準に準拠した署名の 1 つを使用する必要があります。

あなたが自分のやり方でそれをやりたい理由は十分に理解しています。最善の方法は、必要なキャストを含めて、独自の関数myMain()などを必要なシグネチャで記述し、main() から呼び出すことです。

于 2009-10-25T18:52:21.547 に答える
2

The argv pointers shouldn't be const char* const because the program is allowed to change the buffers.

于 2009-10-25T18:11:42.187 に答える
1

As far as I can see from reading the standard, you're being non-standards-compliant. But I can't imagine a compiler that wouldn't let you do this. As in, it'd take more work from the compiler to specifically ban an edge case that is mostly harmless and very obscure.

于 2009-10-25T18:08:50.787 に答える
1

これは、コンパイラがmain. 結局のところ、これは C++ 関数です。したがって、リンカは 2 つの特定の「マングリング」を探します。あなたの定義には、別の壊れた名前があります。

これmainは特別であり (オーバーロードせず、呼び出し可能ではない)、名前マングリングをまったく必要としない可能性があることに注意してください。

于 2009-10-26T11:15:58.397 に答える
0

標準では違法かもしれませんが、ほとんどのランタイムは気にしません。彼らは の整数argcと のポインタをプッシュし、あなたのargvを呼び出し、あなたmainがそれらを正しく解析してくれることを願っています。したがって、ローダーは引数を何として宣言したかを実際には気にしないため、「動作が保証されている」というあなたの範囲では議論の余地があります。

ビルドするmainと、呼び出されます。引数をどのように解析するかはあなた次第です。この質問のほぼ全体と同様に、これはプラットフォーム固有であることを明確にする必要があります。

とは言え、なぜ?

于 2009-10-25T18:12:15.497 に答える
0

ISO/IEC 9899:TC3

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

プログラムの起動時に呼び出される関数は main と呼ばれます。実装は、この関数のプロトタイプを宣言していません。これは、戻り値の型が int で、パラメーターなしで定義されます。

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

または 2 つのパラメーター (ここでは argc および argv と呼ばれますが、宣言されている関数に対してローカルであるため、任意の名前を使用できます):

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

または同等のもの;9) または他の実装定義の方法で。

于 2010-08-03T05:07:04.977 に答える