はじめに
ふとした事で forward 指令の違いに気付きました。
forward 指令
指令 (Directive) とは、ソースコード中の特定の場所でのみ予約語のように扱われるキーワードの事です。forward 指令とは、前方宣言の事で、C 言語の関数プロトタイプ宣言にあたります。
最初期の Pascal には forward 指令がなかったため、呼び出される順番を考慮して手続き/関数を並べる必要がありました。
次のプログラムは宣言されていない forward()
を exec()
から呼んでいるのでエラーになります。
program fwtest(output);
procedure exec;
begin
forward;
end;
procedure forward;
begin
Writeln('Hello,world.');
end;
begin
exec;
end.
このように並び替える必要がありました。
program fwtest(output);
procedure forward;
begin
Writeln('Hello,world.');
end;
procedure exec;
begin
forward;
end;
begin
exec;
end.
この問題を解決するのが、forward 指令です。前方宣言ですね。 ISO 7185:1983 以降で実装されています。
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 の場合
もちろん、コンパイルは通ります。
ISO 7185:1983 Pascal での指令は forward のみです。
■ Delphi の場合
Delphi でもコンパイルは通ります。
■ Turbo Pascal の場合
Turbo Pascal 3.0 で試してみたらエラーになりました。Reserved word
?
マニュアルを確認してみたら forward は 予約語 (reserved word) と書かれています!
Turbo Pascal 5.5 でも予約語でした。
どうやら Turbo Pascal 6.0 の時点で forward 指令へと変更になった模様です。それより前の Turbo Pascal での forward は予約語です。
念のために interface 宣言について
『Turbo Pascal 4.0』で導入されたユニット
においては少々事情が異なります。
unit ユニット名;
interface
implementation
end;
ユニットでは interface 部に手続きと関数のヘッダーを書き、implementation 部でその実装を書きます。C 言語で言うと interface 部が *.h
、implementation 部が *.c
に相当します。
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 部でしか手続きと関数を使わない) 場合には、
unit Hello;
interface
implementation
procedure Proc2;
begin
Write('Hello,world.');
end;
procedure Proc1;
begin
Proc2;
end;
end.
手続きと関数の順序が関係してくるので、必要であれば順序を入れ替えるか、
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 年ですから、当初は予約語で実装されたのもやむを得ないかな、と。
標準 Pascal の指令は forward ただ一つなので、予約語扱いにした方が実装は簡単だと推察されます。
See also: