Delphi で最少のソースコードを書いてみる

# はじめに
Delphi で**最少のソースコード**ってどれだけ短くなるのかを調べてみました。

ここで言う最少のソースコードとはバイト数が最も少なくなるソースコードファイルの事です。
実行ファイルを作れる最小限のソースコードであり、生成される実行ファイルサイズの事ではありません。

# やってみよう
では始めます。検証に使う環境は Delphi 10.3.1 Rio です。

## コンソールアプリケーション
フォームのあるアプリケーションはそれだけでコード量がありますので、コンソールアプリケーションを選択します。

[ファイル | 新規作成 | その他...] から
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/1a7a0686-03bc-6270-e6a7-946956bf49c1.png)
`コンソールアプリケーション` を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/4e221e49-8817-ee0a-682f-96bc6964c43c.png)
この時点のソースコードは以下の通りです。

```pascal
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

begin
  try
    { TODO -oUser -cConsole メイン : ここにコードを記述してください }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
```

※ この辺で一旦読むのをやめて答えを予想してみるのもいいかもしれません！

 - [コンソール アプリケーション (DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)

### 例外処理のコードを削る
今回の用途だったら例外処理は不要ですねー♪

```pascal
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

begin
end.
```

### コンパイラ指令のコードを削る
今回の用途だったらコンパイラ指令も不要ですねー♪

```pascal
program Project1;
uses
  System.SysUtils;

begin
end.
```

`{$APPTYPE CONSOLE}` を削ってもコンソールアプリケーションになります。設定はプロジェクトオプションにあるからです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/be3e1b02-fd91-b587-505a-607fd0df5c2e.png)
普通のコンソールアプリケーションでは `{$APPTYPE CONSOLE}` を付けておくべきです。これを付けておけば *.dpr を単独で配布したとしてもコンソールアプリケーションとみなされます。

\*.dpr を単独で配布された場合、これを開くとプロジェクトオプション用のファイル (*.dproj) が自動生成されます。しかしながら自動生成されたプロジェクトオプションではコンソールアプリケーション生成のスイッチが常にオフになっているため `{$APPTYPE CONSOLE}` のないソースコードはコンソールアプリケーションとみなされません。

`{$APPTYPE CONSOLE}` があったとしても、プロジェクトオプションではコンソールアプリケーション生成のスイッチはオフのままですが `{$APPTYPE CONSOLE}` 指令があるため、コンソールアプリケーションとしてコンパイルされます。

`{$R *.res}` はバージョン情報などのリソースを含めるかどうかなのですが、これも今回の目的には不要です。でも、普段は**実行ファイルにバージョン情報リソースを含めておかないとウィルス対策ソフトに誤検知される事があります**。バージョン情報リソースの有無で結果が異なるって...なんて杜撰なウィルスチェックなのだろう。

 - [［リンク］(DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/%EF%BC%BB%E3%83%AA%E3%83%B3%E3%82%AF%EF%BC%BD)
 - [Application の種類（Delphi）(DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/Application_%E3%81%AE%E7%A8%AE%E9%A1%9E%EF%BC%88Delphi%EF%BC%89)
 - [リソースファイル（Delphi）(DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%EF%BC%88Delphi%EF%BC%89)

### Sysutils を削る
今回の用途だったら Sysutils は不要ですねー♪ そうなると **uses** 句も不要です！

```pascal
program Project1;
begin
end.
```

**uses** に何もなくてもアプリケーションを作ることが可能です。何故なら Delphi (Pascal) には組み込み手続き/関数が用意されているからです。これだけでもアプリケーションは作れます。

 - [Delphi 組み込みルーチン (DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/Delphi_%E7%B5%84%E3%81%BF%E8%BE%BC%E3%81%BF%E3%83%AB%E3%83%BC%E3%83%81%E3%83%B3)

SysUtils は外部ライブラリで、これを使えばもっと簡単にアプリケーションが作れるというだけの事だったりします。

 - [System.SysUtils (DocWiki)](http://docwiki.embarcadero.com/Libraries/Rio/ja/System.SysUtils)

そういえばドキュメントに書かれていない組み込み手続き/関数があるのだとか。

 - [Undocumented intrinsic routines (StackOverflow)](https://stackoverflow.com/questions/30417218/undocumented-intrinsic-routines)

### program ヘッダーを削る
比較的モダンな Pascal では **program** ヘッダーは形骸化しており、Delphi もその例外ではありません。**program** ヘッダーは削れます。

```pascal
begin
end.
```

標準 Pascal では **Program** ヘッダーにパラメータを指定できますが、Delphi はこれを無視します。

 - [プログラムとユニット（Delphi）(DocWiki)](http://docwiki.embarcadero.com/RADStudio/ja/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%A8%E3%83%A6%E3%83%8B%E3%83%83%E3%83%88%EF%BC%88Delphi%EF%BC%89)
 - [Pascal についてのポエム (パンセではない) (Qiita)](https://qiita.com/ht_deko/items/aba9e0b6a6e8d003d34e)
 - [Delphi で Pascal-S をコンパイルする (Qiita)](https://qiita.com/ht_deko/items/77052d1f3c3c1a927034)

### もう削るものは...
Delphi だと **begin** も削れます。

```pascal
end.
```

構造ペインが文句を垂れますが削れます (w
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/da6ae180-c355-a263-95c6-10f467395557.png)
ちなみに FreePascal だと **begin** は必要です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/4b543ae5-ced3-08bf-5cc3-82fb48976064.png)
`{$mode DELPHI}` 付けても通りません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/a736b85b-a39c-9875-f601-d46ced59e86c.png)

### end は...
**end** は削れません (w

# おわりに
ちなみに、この `end.` だけのプロジェクトをリリースビルドでコンパイルした時の実行ファイルのサイズは 42KB でした。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/21785/f0f1731c-1ab7-1912-4f17-2bfcf5b8950c.png)