どう書く? main関数



いろいろ見かけるmainの書き方

 main関数も本や書く人によっていろいろなスタイルをみかけます。いったいどうかくのが正しいのでしょうか。
 まず一つ目の例として<

main()
{
}
 として、何も書かずに始める例をよく見かけます。C言語では型が省略された場合はすべて int 型とみなされますから、これは int を戻り値とする関数として扱われます。しかし最近の流儀ではこれは省略するべきではありません。またまれに return を書いていないプログラムを見かけます。賢いコンパイラならこれは思いっきり warning を食らいます。

 次に見かけるのが

void main()
{
}
 ですね。
 組み込みマイコン用に書くときはこれで正解です。何しろリターンしませんから。ですが通常のOSの場合はmain関数の戻り値はプロセスの終了コードです。戻り値無しとしているわけですからこのままリターンするとでたらめな値が戻り値となってしまい、普通はプログラムが異常終了したと親プロセスに理解されます。ですからこう書く人たちは exit 関数でプロセスを終了させます。ただし、(処理系にもよるのですが) exit は stdlib.h で定義されるれっきとした関数ですから、プログラムサイズがごくわずかですが増加するという欠点がるのと、プログラムが最後まで実行されないという点で全体の流れが乱れているようで私は嫌いです。

 ではどうかくのが一番いいかというと、

int main()
{
}
 と書いてきちんと return するのが一番きれいだと思うのですがどうでしょう。86系の新めのCの本は大体このスタイルのようです。



mainの引数はどうする?

 main関数の引数が必要な場合は

int main(int argc, char *argv[])
 と書きますよね。これで argc にコマンドラインで渡されたパラメーターの個数、argvにパラメーターが格納されます。

 ここでちょっと考えてみるとこれを省略して書けるというのは実は結構気持ちの悪い話でC++では省略可能にするために main 関数のみ例外的に処理されるようになっているようです。どう不気味なのかというと、C++にはタイプセーフリンケージの機構とそれを使った関数のオーバーロードの機能があります。つまり関数の型が違うと名前が同じでもリンカレベルでまったく別の関数になってしまうはずなのです。そのためC++では main 関数以外ではパラメーターが要らないからといって省略することは許されていないのです。この問題は Windows プログラミングで良く生じることで、OSからアプリが呼ばれるという構造上、引数が始めから決められているケースが多く、実際には使わない引数でもちゃんと書かないと動かないのです。ただし、真っ正直に書いてしまうと warnig を食らってしまうのでC++の他の関数的に書くなら

int main(int , char *[])
 とでもなるんでしょうかね。なんか間抜けですね。でも main だけ別扱いというのもなんか互換性を引きずっているようでいい気持ちもしないですが。
 こんなことを気にしてるのって私だけでしょうか?