Rational Developer for System z
Enterprise PL/I for z/OS, Version 3.8, 言語解説書

INTERNAL 属性と EXTERNAL 属性

INTERNAL 属性と EXTERNAL 属性は、名前の有効範囲を指定します。

構文図を読む構文図をスキップする>>-+-INTERNAL-----------------------------+--------------------><
   '-EXTERNAL--+------------------------+-'
               '-(--environment-name--)-'
 

省略形: INTERNAL は INT、EXTERNAL は EXT

environment-name
コンパイル単位の外側で認識されるプロシージャー名または変数名を指定します。

この指定により、宣言中の名前は実質的に内部となり、コンパイル単位の外側では認識されなくなります。 宣言中の名前の代わりに環境名が知られるようになります。

環境名は文字ストリング定数でなければならず、 大文字への変換なしにそのまま使用されます。

以下に例を示します。

  dcl X entry external ('koala');

環境名を区切り文字 (_) で開始することは避けてください。 下線文字で開始される名前は、ライブラリー用として予約されています。

リンカーが環境名を修飾するプラットフォームでは、外部属性を持つ 環境名を指定しても、その名前が変数名と大文字/ 小文字の違いしかない場合は、 その環境名は修飾されます。 次の宣言では、

  dcl abc ext('kLm'), xyz ext('xYz' );

xyz の名前が修飾されます。 環境名の装飾について詳しくは、PL/I for Windows の 「プログラミング・ガイド」の「呼び出し規則」という章の「リンケージに関する考慮事項」を参照してください。

INTERNAL は、内部プロシージャーの入り口名および他のすべての変数 (入り口定数、ファイル定数、およびプログラマー定義の条件を除く) のデフォルトです。 INTERNAL は、その名前が、それを宣言しているブロック内でだけ認識されることを指定します。 別の場所で同じ名前を明示的に宣言すると、別の有効範囲を持つ新しい オブジェクトを参照することになります。これらの 2 つの有効範囲は 相互に重なることはありません。

注:
INTERNAL は、パッケージ内のレベル 1 プロシージャー上で 指定することができます。 パッケージが EXPORTS(*) を指定して宣言してある場合、 INTERNAL プロシージャーはパッケージの外部から不可視になります。

EXTERNAL は、ファイル定数、(内部プロシージャー以外の) 入り口定数、およびプログラマー定義の条件のデフォルトです。 EXTERNAL 属性を持つ名前は、別々の外部プロシージャー内で、または外部プロシージャーに含まれているブロック内で複数回宣言することができます。 EXTERNAL 属性を持つ同じ名前を 2 回以上宣言した場合、それらの宣言はすべて同じデータを参照します。 EXTERNAL 属性を持つ名前の各宣言の有効範囲は、 そのアプリケーション内でのその名前 (EXTERNAL 属性を持つもの) の すべての宣言の有効範囲を包含します。

大構造体または共用体の名前を複数のブロックで EXTERNAL として 宣言する場合、対応するメンバー名は異なっていてもかまいませんが、 メンバーの属性は同じでなければなりません。

次に例を示します。

ProcA: procedure;
declare 1 A external,
2 B,
2 C;

·
·
·
  end ProcA;   %process; ProcB: procedure; declare 1 A external, 2 B, 2 D;
·
·
·
end ProcB;

A.BProcA 内で変換されると、 それは ProcB についても変換され、逆の場合も同様です。 A.CProcA 内で変換されると、 A.DProcB について変換され、逆の場合も同様です。

構造体と共用体のメンバーは、常に INTERNAL 属性を持ちます。

同じ名前の外部宣言はすべて同じデータを共用するため、それらの宣言の結果はすべて同じセットの属性にならなければなりません。 EXTERNAL の名前が別の外部プロシージャーで宣言されるときは、 ユーザーは属性が確実に一致するようにしなければなりません。図 9 は、さまざまな宣言とその有効範囲を説明しています。

図 9. 各種宣言の有効範囲の例
         Scope_Example:  package exports(*);
 1         A: procedure;
 2            declare S character (20);
 7            dcl Set entry(fixed decimal(1)),
 7                Out entry(label);
              call Set (3);
 9         E: get list (S,M,N);
 8         B: begin;
 4,5            declare X(M,N), Y(M);
                get list (X,Y);
                call C(X,Y);
 9,5       C:  procedure (P,Q);
                  declare
                    P(*,*),
                    Q(*),
 12,2               S binary fixed external;
                  S = 0;
 6                do I = 1 to M;
                    if sum (P(I,*)) = Q(I) then
 8                     go to B;
                    S = S+1;
                    if S = 3 then
 9                     call Out (E);
                    Call D(I);
 8         B:  end;
           end C;
 9         D:  procedure (N);
                 put list ('Error in row ',
 2,3                   N, 'Table Name ', S);
           end D;
           end B;
           go to E;
           end A;
 9        Out:  procedure (R);
                Declare
                  R Label,
 11               (K static internal,
 11,7                L static external) init (0),
 12               S binary fixed external,
                  Z fixed decimal(1);
                K = K+1; S=0;
                if K<L then
                  stop;
 10             else go to R;
          end;
          Set:  procedure (Z);
                declare Z fixed dec(1);
 7              L=Z;
                declare L external init(0);
                return;
                end;
            end Scope_Example;

 1 
A は外部プロシージャー名です。 この有効範囲は、ブロック A の全体と、 A が外部として宣言されているほかの任意のブロックです。
 2 
S は、ブロック A とブロック C で 明示的に宣言されています。 文字変数の宣言は、ブロック C を除く ブロック A 全体に適用されます。 固定 2 進値宣言は、ブロック C の内部でのみ適用されます。 D はブロック C から呼び出されますが、D 内の PUT ステートメントでの S への参照は文字変数 S への参照であり、ブロック C 内で 宣言されている S への参照ではありません。
 3 
N はブロック D 内のパラメーターとして 書かれていますが、このブロックの外でも使用されます。 パラメーターとして書かれているため、D 内で N の明示宣言が確立されます。 D の外部での参照により、 ブロック A 内での N の暗黙宣言が行われています。 名前 N の 2 つの宣言は、別々のオブジェクトを参照します。 ただし、この場合、これらのオブジェクトは同じデータ属性を持ちます。 データ属性は、デフォルトにより、FIXED BINARY(15,0) と INTERNAL です。DEFAULT(ANS) の場合の精度は (31,0) です。
 4 
XYB 全体で認識され、B 内部のブロック C または D から 参照できます。ただし、B の外側の A 部分からは 参照できません。
 5 
PQ はパラメーターです。 したがって、ブロック内でこれらの名前の宣言がほかになければ、 パラメーター・リストに指定されているだけで コンテキスト宣言がされていることになります。 しかし、PQ が配列であることを 指定するには、別個の明示宣言が必要です。 引数 XY は配列として宣言されており、 ブロック C 内で認識されていますが、PQ も 配列であることを指定するには、DECLARE ステートメントでそれらを宣言しなければなりません。 (アスタリスク表記は、パラメーターの境界が引数の境界と 同じであることを示します。)
 6 
IM は、 外部プロシージャー A では明示的に宣言されていません。 したがって、これらは暗黙に宣言され、A 全体で認識されます。 ただし、I はブロック C の中でしか使われません。
 7 
例の中の外部プロシージャー OutSet には、 これら両方に共通の L という外部宣言があります。 これらは、プロシージャー A で ENTRY 属性を付けて 明示的に宣言しなければなりません。ENTRY は EXTERNAL を暗黙指定するため、2 つの 入り口定数 SetOut は、2 つの外部プロシージャー全体で認識されます。
 8 
ラベル B はこのプログラムに 2 回現れます。 最初は A 内で開始ブロックのラベルとしてであり、 明示宣言となります。次にブロック C 内のラベルとして宣言され、END ステートメントの接頭部として使用されます。 したがって、C 内の go to B ステートメントは、C 内の END ステートメントのラベルを参照することになります。 ブロック C の外側では、B への参照は開始ブロックのラベルへの参照となります。
 9 
ブロック CD は、B 内部のどこからでも 呼び出せますが、B の外の A 部分や別の 外部プロシージャーからは呼び出せません。 同様に、ラベル E は外部プロシージャー A 全体で 認識されているため、E への制御の伝送は A 内部の どこからでも行うことができます。 ただし、ブロック C 内のラベル B は、 C の中からのみ参照できます。GO TO ステートメントによってブロックの外への伝送ができます。 しかし、ネストされたブロックへのそのような伝送は、 一般的に行えません。 この例外となるケースは外部プロシージャー Out に 示されています。ここでは、ラベル E が ブロック C から引数として ラベル・パラメーター R に渡されています。

GET ステートメントと PUT ステートメントにはファイルが 指定されていないため、SYSIN と SYSPRINT は 暗黙宣言されていることに注意してください。

 10 
ステートメント else go to R; は、 制御をラベル E に伝送します。EA 内で宣言 されており、Out 内では知られていない場合でも同様です。
 11 
変数 K (INTERNAL) と L (EXTERNAL) は、Out プロシージャー・ブロック内で STATIC として宣言されています。 それらの値は Out への呼び出しの間で保護されています。
 12 
プロシージャー Out の中の S を プロシージャー C の中の S と同じものとして識別するために、 どちらも属性 EXTERNAL を付けて宣言されています。

Terms of use | Feedback

This information center is powered by Eclipse technology. (http://www.eclipse.org)