本物のC

C の詳細:mainの書き方


main関数の書き方には資料によりかなりばらつきがある。

main()

空の括弧()は関数の宣言では「引数については何も指定しない」意だが、関数の定義では「引数を取らない」意となる6.7.5.3#14。よってmain()でもmainは引数を取らない事になり、この形は5.1.2.2.1#1の "or equivalent," により許容される様に見える。

しかしint main(void) { ~ }が parameter type list を持ち関数宣言としても働く6.9.1#7一方、int main() { ~ }は文法上 identifier list が空の場合として解釈されるので6.7.5#1 parameter type list を持たず宣言としては働かない。この点を考慮するならば二つの書き方は equivalent とは言えず、main()は規格に沿わない事になる。

また空の括弧を使う書き方は以下のデメリットを持つ:

以上の事情を勘案すれば、main()は用いるべきでないと言えるだろう。

(参考:「Is int main() { } (without “void”) valid and portable in ISO C? - Stack Overflow」)

K&R

K&R の初版では

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

というコードが見られるが、これは上と同じく identifier list を持つ関数定義である。identifier list が空でない場合、それぞれの引数の型を後続の行で宣言する6.9.1#7

この書き方も obsolescent feature とされている6.11.7#1ので使うべきでない。(K&R の第二版では修正されている。)

return 0;を書かない

returnを書かない場合、C99 ではmain}へ到達すると 0 が返さる5.1.2.2.3#1。しかしそれ以前の規格ではその場合の記述が無い様で、また悲しい事に gcc はデフォルトで C89 のGNU拡張に従う為-std=c99を指定しないと 0 が返る保証はない。

(参考:C89 の 2.1.2.2、「gccのマニュアル」の -std= の項の gnu89)