main関数でargcとargvの名前を変更しても安全ですか?


82

多くのプログラムは、多くの引数と文字列の配列に標準名を使用します。main関数のプロトタイプは次のようになりますint main(int argc, char *argv[]);。しかし、これらの変数にカスタム名を選択した場合、何かが壊れますか?

例えば int main(int n_of_args, char *args[]);

コンパイラーのコンテキストでは、すべてが正常です。これらの変数はmain関数に対してローカルであるため、任意の名前を付けることができます。そして、単純なコードは完全に構築され、実行されます。ただし、これらの名前はプリプロセッサによって使用される場合があります。では、これらの引数の名前を変更しても安全ですか?

PS個人的には、これらの名前は非常によく似ており、1文字だけが異なるため、悪いと思います。しかし、誰もが何らかの理由でそれらを使用しています。


21
はい、完全に安全です。
David Hoelzer 2016

55
すべての答えが言うように、はい、それは安全です。しかし、そうしないでください。誰もが何であるかargcを知っていargvます。n_of_argsそしてargsそれはあなたの聴衆ではありません- CまたはC ++を知らない誰かに明確であるかもしれません。
キース・トンプソン

4
あなたはこれ行うことができます、これを行うのに十分な理由ではありません。誰もがそれらが何であるかを知っており、彼らはそれらがそのようになることを期待しています。
SergeyA 2016

10
質問が正確に「カスタム名を選択した場合、何かを壊すだろうか」である場合、正確な答えは「はい、定評のある伝統を壊すでしょう」です;)
Frax 2016

12
それらを裏返すだけです!..そして最初からあなたは雇用保障の基礎を築いています:)
yano 2016

回答:


121

はい、有効な変数名を使用している限り、安全です。それらはローカル変数であるため、それらのスコープはmain関数を超えません。

C標準のセクション5.1.2.2.1から:

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

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

または二つのパラメータを有する(ここでいうようargcargv任意の名前を使用することができるが、それらが宣言された関数に対してローカルであるように)。

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

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

そうは言っても、argcと以外のものをargv使用すると、これらのパラメーターの従来の名前に慣れている他の人がコードを読んで混乱する可能性があります。クレアリティの側で間違いを犯したほうがいいです。


38

名前argcargvは、C ++ 11より前のC ++標準によって実際に義務付けられていました。それは述べました:

すべての実装では、次のmainの定義の両方を許可する必要があります。

int main ()

そして

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

そして上の要件を議論するようになったargcargv

したがって、技術的には、異なる名前を使用するプログラムは標準に準拠しておらず、コンパイラはそれを拒否することができました。もちろん、実際にそうしているコンパイラはありません。comp.std.c ++のこのスレッド、またはこのC ++ 03ドラフト標準のセクション3.6.1を参照してください。

これはほぼ間違いなく単なる見落としであり、C ++ 11で変更されました。

すべての実装で両方が許可されます

  • ()を返す関数int
  • int、へのポインタへのポインタchar)を返す関数int

main(8.3.5)のタイプとして。後者の形式では、説明のために、最初の関数パラメーターが呼び出さargcれ、2番目の関数パラメーターが呼び出されargvます。


29

これらのパラメータの名前は、好きなように安全に変更できます。

 int main(int wrzlbrnft, char* _42[]) {
 }

名前は砂で書かれています。最終的にコンパイルされたコードには影響しません。


重要なのは、宣言と定義のパラメータータイプが実際に一致することだけです。

main()関数のシグネチャは本質的に次のように宣言されます

 int main(int, char*[]);

実装でそれらを使用する必要がある場合は、実際にそれらに名前を付ける必要があります。前述のように、どの名前が使用されているかは実際には関係ありません。


5
あなたがそれを置くとき、いくつかの識別子だけが「砂に書かれている」。関数名は確かにそうではありません。
スティーブコックス

1
@SteveCox 「関数名は確かにそうではありません。」結局、彼らはそうです。砂粒の数字だけ:-P ...
πάνταῥεῖ

3
わかりましたが、真剣に。コンパイル後も、オブジェクトコードには関数名が含まれています。そうでなければリンクは機能しません
スティーブコックス

4
@πάνταῥεῖ:それらを削除するために特別な努力をしない限り、関数名は最終的な実行可能ファイルに残ります。
Nick Matteo

1
@Kundor:Windowsでリンクした後、すべての非特殊関数は名前を保持しません
Dani

15

はい。それは安全で、奇妙に見えますが、何も壊すことはありません。


7

はい、別の名前を使用しても安全です。

個人的argcargvは、これは伝統的なものであり、コードを操作する可能性のある他のすべてのCプログラマーに広く知られ、よく知られているため、お勧めしません。長期的には、独自の特別な異なる名前を使用すると、名前の方が好きなので、読者を救うよりもはるかに多くの混乱やフラストレーションを引き起こすことになります。

「ローマにいるときは、ローマ人と同じようにしてください。」


しかし、異なる名前を使用する必要がある非常に明白なシナリオはほとんどありません。悪名高いシナリオはglutInit(&argc, argv)、GLUTを初期化することです。ここでは、必要がない限り、GLUTがコマンドライン引数を使い果たしないように、引数を異なる方法で宣言して初期化する必要があります。SOリンク
user3078414 2016

@ user3078414興味深い例ですが、変数に名前を付ける必要があることについて、それがどのように言っているのかわかりません。他の質問の例によると、簡単に書くことができますint dummyargc = 1; char *dummyargv[1] = {(char*)"Something"}; glutInit(&dummyargc, dummyargv);
スティーブサミット

ありがとう、@ steve-summit。一部のAPIドキュメントは誤解を招く可能性があるため、このスレッドargc argvは、貢献する回答と同様に、命名規則を強調するのに最も役立ちます。できれば別の名前を使用する例としてコメントを付けました。これがSOリンクです
user3078414 2016

5

はい、必要に応じて名前を変更できます。これらは単なる関数パラメータ名であり、それ以上のものではありません。


3

私は誰もが技術的なc ++ルールをうまくカバーしていると感じています:答えはイエスです。伝統と、この1つの特定の機能が特別で象徴的であり、これに基づいて変更されない有効なポイントが含まれているという事実はさておきましょう。

選択の哲学が議論されることはめったにないと感じることがよくあります。そのため、これが最初に求められた理由にとって重要であると感じているので、この問題についての視点を提供したいと思います。

私へのこの質問は、一般的にコードで英語を表現する際の選択を含みます。特に、速記が似たようなテキストになっている場合は、速記の説明に悩まされているようです。ただし、あなたの例では、argnをn_of_argsに変更すると、あるタイプの速記を別の形式の速記に変更するだけで、実際の付加価値はありません。説明やその他の表示プロパティです。

「数字」という単語は「n」の文字に置き換えられました。

アンチショートハンドの哲学によってショートハンドの名前を変更する場合は、次のようなものがより適切に思えるかもしれません。

main(int軍のカウント、文字**引数ベクトル)

私はいつも2つのことを考えています:それらが何であるかによって、そして/またはそれらの暗黙の使用法によって物事に名前を付けること。これをargumentVectorと呼ぶことは、ベクトルであるという特性が二重間接参照**によって暗示されるため、私には冗長です。したがって、私がコードをどのように書くかについてのより良い長い手は次のとおりです:**引数。

argumentsCountという名前の変数はintとして宣言されており、Countを負にすることはできませんが、intを負にすることはできます{unsignedの方が良い}と言う人もいます。

繰り返しになりますが、それが何であり、どのように使用されるかが、この解釈に影響を及ぼします。それがカウントである場合、私はそれが決して負になることはないと思います。結局のところ、どうすれば-2個のリンゴを数えることができますか。私はあなたが2つのリンゴを借りていると言うでしょう。数字の場合、否定的なケースが考えられます。これが、「の」という追加の単語があなたにとっておそらく重要である理由です。それと、おそらくコレクションによって参照される番号は、コレクション自体のプロパティではなく、特定のアイテムを意味します。つまり、argumentsNumber = 5は特定の引数を意味しますが、numberOfArgumentsは意味しません。

main(int maxArgumentsIndex、char **引数)。

これにより、あいまいさがなくなります。それをインデックスと呼ぶことは、否定的なケースの曖昧さを取り除き、それが何であるか、そしてさらにそれを使用する方法を説明します。また、英語の表現では、maxは絶対値であり、この値を変更するコードを書くと奇妙に感じることを意味します(constである必要があります)。「引数」は複数形であるため、ここでは意味があり、それが何であるか、およびすでにどのように使用されるべきかを説明しています。インデックスはCount / NumberOfの-1であるため、このように解釈することでさえ危険な場合があります。5つの引数は4のmaxIndexを生成します!!

他の関数と私は完全に使用します:

void function(const unsigned int maxArgumentsIndex、const char **引数)

すべての状況がロングハンド記述子に値するわけではありません。実際、特にVec3f、Matrix、Quaternionなどの数学クラスを作成する場合は、速記で読みやすくなることがあります。ほとんどの場合、言語言語ではなく数学言語と一致させようとします。 。フロートx、y、zvrs。floatxComponentなど。

私はこれがすべてスタイルの選択であることを理解していますが、選択を意識することは長期的には本当に役立ちます。配列が複数形で書かれていない場合、経験豊富なプログラマーが煩わされることを保証しますが、繰り返しになりますが、mainは存在の特別な散文です;)


2

C標準に従って、はい、名前を変更できます。影響はありません。私が理解したように、C言語では、デフォルトのキーワード/タイプ/トークン名は目的/使用法で定義されていたので、同じように定義された名前です

argc --> argument count

argv --> argument vector

これは使用法の観点からも意味があるので、期待する任意の名前に変更できます Reserved names

GCCでは、プログラムの実行mainは、パラメーターに依存しない関数名で開始されます。

マイクロコントローラー用のスタンドアロンプ​​ログラムを作成する場合、名前を気にする必要はありません。main代わりに、独自のプログラムを定義しname、関数を指すようにアセンブリのentry_pointを変更できます。これは、コントローラーコンパイラーと事前定義されたコントローラーソースコードの可用性に依存します。私はCode-warriorの下のFreescaleコントローラーでこれを行いました。

私のメモ:

コードをより見やすく読みやすくするには、一般的な標準/コードスタイルに従うことをお勧めします


0

コンパイラに関する限り、安全です。

これが引き起こす可能性のある唯一の問題は混乱です。あなたのコードを読む人は、これら2つの変数に標準の名前があることを期待します。あなたもこのようなことをすることができます:

int main(int foo, char ** bar)
{
    int argc;
    float argv;

しかし、これがどれほど悪い習慣になるかを言う必要はないと思います。


-1

変数名が気に入らない場合は、マクロ#defineで置き換えてみませんか。

#define yourCounterName argc
#define yourVectorName  argv 

リスクを冒さず、「クリーンなソリューション」を作成します。


これらは定数ではなく、単なる置換です。
David Dunham 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.