標準 Pascal と Turbo Pascal と Delphi の forward 指令

# はじめに

ふとした事で **forward** 指令の違いに気付きました。

# forward 指令
**指令 (Directive)** とは、ソースコード中の特定の場所でのみ予約語のように扱われるキーワードの事です。**forward** 指令とは、前方宣言の事で、C 言語の関数プロトタイプ宣言にあたります。

最初期の Pascal には **forward** 指令がなかったため、呼び出される順番を考慮して手続き/関数を並べる必要がありました。

次のプログラムは宣言されていない `forward()` を `exec()` から呼んでいるのでエラーになります。

```pascal
program fwtest(output);

  procedure exec;
  begin
    forward;
  end;

  procedure forward;
  begin
    Writeln('Hello,world.');
  end;

begin
  exec;
end.
```

このように並び替える必要がありました。

```pascal
program fwtest(output);

  procedure forward;
  begin
    Writeln('Hello,world.');
  end;

  procedure exec;
  begin
    forward;
  end;

begin
  exec;
end.
```

この問題を解決するのが、**forward** 指令です。前方宣言ですね。 ISO 7185:1983 以降で実装されています。

```pascal
program fwtest(output);

  procedure forward; forward; { forward directive }

  procedure exec;
  begin
    forward;
  end;

  procedure forward;
  begin
    Writeln('Hello,world.');
  end;

begin
  exec;
end.
```

**forward** は予約語ではなく指令なので、`forward()` という名前のルーチンを書いても問題ありません。Qiita のパーサーは **forward** を予約語として扱っているようですね ┐(´∀｀)┌ﾔﾚﾔﾚ

## ■ 標準 Pascal の場合

もちろん、コンパイルは通ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/980e24d3-7b26-b72c-eab2-d8e988f9f84c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/ab995925-de6f-e801-c0b7-30f78030c0e1.png)

:::note info
ISO 7185:1983 Pascal での指令は **forward** のみです。
:::

## ■ Delphi の場合

Delphi でもコンパイルは通ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/930445e9-5d95-7916-dd0f-821ed21c0bb4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/95c34257-9a90-4fd0-48be-725ff5ff0260.png)


## ■ Turbo Pascal の場合

Turbo Pascal 3.0 で試してみたらエラーになりました。`Reserved word` ？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b1f46a86-25e3-1b8d-d602-1dc8e5b5f877.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/4be01a32-bd50-efa1-3bad-a2f2820d0001.png)

マニュアルを確認してみたら **forward** は **予約語 (reserved word)** と書かれています！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/fdc79aef-1f73-1c20-b8dd-b2dbaa9e13f4.png)

Turbo Pascal 5.5 でも予約語でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/57d25850-58ce-ae09-9ddb-3855878033f3.png)

どうやら Turbo Pascal 6.0 の時点で **forward** 指令へと変更になった模様です。それより前の Turbo Pascal での **forward** は予約語です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/fd76d7de-ed7e-9974-74de-5f63bb58cfb0.png)

# 念のために interface 宣言について

 『Turbo Pascal 4.0』で導入された`ユニット` においては少々事情が異なります。

```pascal
unit ユニット名;

interface

implementation 

end;
```

ユニットでは **interface** 部に手続きと関数のヘッダーを書き、**implementation** 部でその実装を書きます。C 言語で言うと **interface** 部が `*.h`、**implementation** 部が `*.c` に相当します。


```pascal
unit Hello;

interface

procedure Proc1;
procedure Proc2;

implementation 

procedure Proc1;
begin
  Proc2;
end;

procedure Proc2;
begin
  Write('Hello,world.');
end;
end.
```


**interface** 部に手続きと関数のヘッダーが書かれていれば、**implementation** 部での手続きや関数の順序を考慮する必要はありませんが、**interface** 部に手続きと関数のヘッダーを書かない...つまり、手続きと関数を他のプログラムやユニットから使わない (このユニットの **implementation** 部でしか手続きと関数を使わない) 場合には、

```pascal
unit Hello;

interface

implementation

procedure Proc2;
begin
  Write('Hello,world.');
end;

procedure Proc1;
begin
  Proc2;
end;
end.
```

手続きと関数の順序が関係してくるので、必要であれば順序を入れ替えるか、

```pascal
unit Hello;

interface

implementation

procedure Proc2; forward; { forward directive }

procedure Proc1;
begin
  Proc2;
end;

procedure Proc2;
begin
  Write('Hello,world.');
end;
end.
```

**forward** 指令を指定する必要があります。

# おわりに

私は Delphi -> 標準 Pascal -> Turbo Pascal の順で触ったので、Turbo Pascal の多くのバージョンで **forward** が予約語だった事を知りませんでした。

Pascal は **begin** **end** のような綴り記号 (予約語) が多いので、オブジェクト指向プログラミングにおいてはそれが弊害に成り得るのでしょう。Turbo Pascal 6.0 で指令になったのも解る気がします…メソッドで **forward** とか使いそうですものね。

**forward** が ISO 7185 に盛り込まれたのが 1983 年、もちろんそれ以前にドラフトはあったのでしょうけれど、Turbo Pascal 1.0 のリリースが同 1983 年ですから、当初は予約語で実装されたのもやむを得ないかな、と。


:::note
標準 Pascal の指令は **forward** ただ一つなので、予約語扱いにした方が実装は簡単だと推察されます。
:::

**See also:**

 - [前方宣言とインターフェイス宣言 (DocWiki)](https://docwiki.embarcadero.com/RADStudio/ja/%E6%89%8B%E7%B6%9A%E3%81%8D%E3%81%A8%E9%96%A2%E6%95%B0%EF%BC%88Delphi%EF%BC%89#.E5.89.8D.E6.96.B9.E5.AE.A3.E8.A8.80.E3.81.A8.E3.82.A4.E3.83.B3.E3.82.BF.E3.83.BC.E3.83.95.E3.82.A7.E3.82.A4.E3.82.B9.E5.AE.A3.E8.A8.80)
 - [11.3. 前方宣言 (Forward declaration) (Qiita)](https://qiita.com/ht_deko/items/b93ac03bfee002f17137#113-%E5%89%8D%E6%96%B9%E5%AE%A3%E8%A8%80-forward-declaration)