main関数の「return 0;」は、OSにプログラムが安全に終了したことを伝えるという意味合いを持つ。
しかし実際には、main関数の「return 0;」を書いていない人もしばしば見かける。
ということで、今回は「return 0;」を書くのと書かないのとではどのような違いが生じるのかをアセンブラで調べてみる。
まず、こちらは「return 0;」を書いた場合のソースコード。
int main(void){ return 0; }
このソースを次のコマンドでコンパイルして
gcc -m32 main.c -o main
次のコマンドで逆アセンブルすると
objdump -d main
main関数の部分は次のようなアセンブリになっている。
000004ed <main>: 4ed: 55 push %ebp 4ee: 89 e5 mov %esp,%ebp 4f0: e8 0c 00 00 00 call 501 <__x86.get_pc_thunk.ax> 4f5: 05 e7 1a 00 00 add $0x1ae7,%eax 4fa: b8 00 00 00 00 mov $0x0,%eax 4ff: 5d pop %ebp 500: c3 ret
このアセンブリのミソは「mov $0x0, %eax」の部分で、これが「return 0;」に対応している。
さて、次は「return 0;」を書かなかった場合について調べてみる。
先程と同様に次のソースコードをコンパイルする。
int main(void){ }
すると、次のようなアセンブラが生成された。
000004ed <main>: 4ed: 55 push %ebp 4ee: 89 e5 mov %esp,%ebp 4f0: e8 0c 00 00 00 call 501 <__x86.get_pc_thunk.ax> 4f5: 05 e7 1a 00 00 add $0x1ae7,%eax 4fa: b8 00 00 00 00 mov $0x0,%eax 4ff: 5d pop %ebp 500: c3 ret
こちらのコードにも「mov $0x0, %eax」の記述がある。
つまり、僕の環境では、賢いコンパイラが「return 0;」を書き忘れたプログラマに変わってコードを挿入してくれたらしい。
結果としては、main関数の中に「return 0;」を書いても書かなくても、「return 0;」は自動的に挿入されることになるらしい。
しかし、環境によっては「return 0;」を書かない場合は「mov $0x0, %eax」がないままになる環境もあるらしいので、「return 0;」は書くべきだと言えるだろう。