最近、本業が忙しく、記事の更新ができてないし、書くネタがない。。。
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 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。