dポイントプレゼントキャンペーン実施中!

C言語での質問です。
引数を取るような main 関数は

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

とされていますが、argvの指す文字列を変更する、というのはいくら何でもまずいので、

int main( int argc, const char *argv[]){~}

あるいは

int main( int argc, const char const * const * argv){~}

の方がいいのではないでしょうか?
何故、constを付けない形が出回っているのでしょうか?

A 回答 (13件中11~13件)

>argv[1] の内容を書き換えてバッファオーバーフロなどなどが起こったら


>何が起こるか分からないですし。

それを言うなら、すべての配列をconstにしなければならない。

この回答への補足

バッファオーバーフローに言及したのは私のミスです。話が発散してしまいますから。取り合えず、オーバーフローしない場合でも、パラメータを書き換えるメリットがあるのか?を知りたいです。また、デメリットもあり得るから疑問だったし。
プログラム名やパラメータがメモリ内のどこに収容されているかは、OSなどに依存するでしょうから、下手に書き換えると動作がおかしくなる可能性があるような気がしまして。また、argvを書き換えるプログラムを書いたとき、後になって、やはり、元のパラメータが何だったか知りたくなると、プログラムの書き換えが大変だし

補足日時:2014/09/14 09:07
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございました。
>それを言うなら、すべての配列をconstにしなければならない。
あるいは、書き換え可能文字列の配列を作るときに、strncpyなどなどを使えるように、文字列幅の情報が得られるようにする、などもありますが、argvでは使えなさそうですね。
バッファオーバーランなどの問題に関しては、自力で調べてみて、どうしても分からなければ、別質問とさせていただきます。

お礼日時:2014/09/22 22:39

変数は変数であって、定数には成れない



男の子が女の子になれないのと一緒

今の世の中、稀に例外もあるので喩えとして少し弱いが・・・・

この回答への補足

#include <stdlib.h>
質問の仕方がまずかったです。規格ではなぜconstではないか?が疑問だったのです。argvの値は関数名やパラメータですから、これを変更可能にする意味があるのか?ということです。
あざとい例ですが。

#include <stdlib.h>
int main( int argc, char *argv[] ){
char *av[3]={NULL, "abc", "def"};

if( argc>1 ){
argv[1][0] = 'X';
return EXIT_SUCCESS;
}

main( 3, av );
return EXIT_SUCCESS;
}

これだと、コンパイルは警告なしで通ります。しかし、実行時にアクセス違反で異常終了します(処理系によりますが)。argv に const が付いていれば、コンパイルエラーになるのでエラーが分かりやすいです。

補足日時:2014/09/14 08:54
    • good
    • 0
この回答へのお礼

どうもありがとうございます。
argvの仕様が、変更可能だったのですね。

お礼日時:2014/09/22 22:41

規格(JIS X3010:2003)上、




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

のどちらかを使うとなっているからです。
勝手に規約を無視しちゃいかんでしょ。

この回答への補足

いや、何故、規格で constが入っていないのか? が疑問なのですが。
歴史的事情なのか(初期のCにはconstがなかったし)? argc>2で argv[1] の内容を書き換えてバッファオーバーフロなどなどが起こったら何が起こるか分からないですし。

補足日時:2014/09/13 21:52
    • good
    • 0
この回答へのお礼

どうも、ありがとうございました。
他の方のご回答もあって、何故そういう規格になっているのか分かりました。

お礼日時:2014/09/22 22:43

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!