2017/03/21

[c/c++]main関数の引数

最近、本業が忙しく、記事の更新ができてないし、書くネタがない。。。
1週間空けるのも嫌なので、Cのmain関数のことを調べ直すことにした。

 

普段フリースタンディング環境を使うことが多いので、main関数はあってもなくてもよいというか、名前は何でもよいけど慣習として使っておこう、くらいのイメージしか持っていない。
関数とは書いたけれども、returnされてもやることがないので、スタックを消費するのも嫌だからコールじゃなくてジャンプさせている、という人も多いんじゃなかろうか(そしてmainの最後は無限ループになっている)。

 

ただ、普通のホスト環境では、main関数は重要だ。


今回もオライリーの『Cクイックリファレンス』を読む。
「7.1.5 main()関数」だ。

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

この両者がC標準とのこと。
引数無しでもいいんだ。。。

これに加えて、次の形式もサポートしていることが多いのだと。

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

envpは環境変数で、getenv()を使ってアクセスできるそうだ。

 

main()の特徴として、returnを書かずにブロックが終わった場合、自動的に0を返すことになっている。
そして、0はstdlib.hのEXIT_SUCCESSと同じ値。
また、main()の終了は、exit()の呼び出しと等価とのこと。

exit()はちょっと特別扱いされていると思っていたのだ。
atexit()でexit時に呼び出す関数が登録できるというところが不思議だったのだ。
説明文を読むと「exit()かmain()のreturn」と書かれているので、同じ扱いなのだな。


昔、C++で作っていたとき、グローバル変数で2つのclassのインスタンスをそれぞれ作り、片方のclassがもう片方のclassのstatic値をコンストラクタで参照するようにしていたのだが、最初は動いていたのに、プログラムを書き換えているうちにうまく動作しなくなった、ということがあった(あまり覚えてないが。。)。

グローバル変数のコンストラクタはどういう順番で動くかはっきりせず、コンストラクタが呼ばれていないと値が設定されないので、最終的にはコンストラクタで初期化は行わず、classに初期化関数を追加してmain()で呼ぶ、というような対処をしたような気がする。

mainが呼ばれる前後の混沌とした状態は制御が難しいので、なるべくmain後の安定した状態で処理を順番に行った方がよいな、と思ったのでした。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。