gcc -nostartfiles その2

gcc で -nostartfiles オプションをつけると、標準スタートアップファイルのリンクが行われないため、できあがりの実行ファイルサイズが大幅に小さくなる。

しかしながら、スタートアップルーチンが正常に機能しないのではないだろうか。その疑問への回答の一つとなる検証用コードを以下に記す。

ソース

#include <windows.h>
void hello() {
  MessageBox(NULL, TEXT("Hello, world!"), TEXT(""), MB_OK);
}
int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cl, int cs) {
  return 0;
}
  1. コードの先頭で windows.h をインクルードする
  2. 次に、メッセージボックスを表示するだけの関数 hello を定義する
  3. 最後に、return 0 するだけの関数 WinMain を定義する

ふつうにコンパイル

まずは、このコードを gcc -mwindows hello.c -o hello.exe コマンドでごく普通にコンパイル&リンクし、生成された hello.exe を実行してみる。




すると、予想通り、何も起こらない。関数 hello は、定義しているだけで、呼び出しは行っておらず、関数 WinMain においても、return 0 以外の処理を書いていないため、ウィンドウもメッセージボックスも何も表示されずに、hello.exe は終了する。

-nostartfiles でコンパイル

次に、このコードを gcc -mwindows -nostartfiles hello.c -o hello.exe コマンドで、コンパイル&リンクしてみる。すると、さっきと同じように、hello.exe が生成されるので、それを実行する。

Hello, world!

意外なことに、画面上には、「Hello, world!」と書かれたメッセージボックスがポップアップする。

しかも、このメッセージボックスを閉じても、hello.exe は終了せず、バックグラウンドで生き延びていることをタスクマネージャで確認することができる。