名前の適用対象となるプログラム部分は、 その名前についての宣言の有効範囲 と呼ばれます。 ほとんどの場合、名前の宣言の有効範囲は、プログラム内で 名前が宣言される位置によって完全に決定されます。 暗黙宣言は、名前が外部プロシージャーの PROCEDURE ステートメントの 直後にある DECLARE ステートメントで宣言されたものと見なされます。
名前がプログラム全体に対して同じ意味を持つ必要はありません。 ブロック内で明示的に宣言された名前は、そのブロック内だけで意味を持ちます。 そのブロックの外部では、同じ名前がそこでも宣言されていない限りその名前は認識されません。 名前を宣言するたびに、その有効範囲が確立されます。この場合、その外側ブロック内の名前は、別のデータ項目を参照することになります。 このため、ローカル定義を指定することにより、プログラムのほかの部分で使用されているすべての名前を知らなくても、プロシージャーまたは開始ブロックを作成することが可能になります。
下記の例で、A の実際の出力は C.A、 つまり 2 です。 B の出力は、プロシージャー X で 宣言されたとおり 1 です。
X: proc options(main);
dcl (A,B) char(1) init('1');
call Y;
return;
Y: proc;
dcl 1 C,
3 A char(1) init('2');
put data(A,B);
return;
end Y;
end X;
したがって、ネストされたプロシージャーでは、 PL/I は現行ブロック内に宣言された変数を使用してから、 包含ブロックで宣言された変数を使用することになります。
名前の宣言の有効範囲を理解するためには、 包含された および内部にある という 2 つの 用語を理解しなければなりません。
PACKAGE、PROCEDURE、または BEGIN ステートメントから、 それに対応する END ステートメント (BEGIN、PACKAGE、 および PROCEDURE ステートメントの条件接頭語も含む) までの 間にあるブロックの全テキストは、そのブロックに包含されると 見なされます。 ただし、ブロックに適用する任意の ENTRY ステートメントのラベルと同様に、ブロックの先頭にある BEGIN または PROCEDURE ステートメントのラベルは、そのブロックに含まれません。 ネストされたブロックは、それらを包むブロックに包含されます。
ブロックに包含されるテキストのうち、そのブロック内の ネストされているほかのブロックに包含されていないものは、 そのブロックの内部にあると見なされます。 プロシージャーの入り口名 (および BEGIN ステートメントのラベル) は、そのブロックに含まれません。 したがって、プロシージャーの入り口名は、包含ブロックの内部にあることになります。 外部プロシージャーの入り口名は、その外部プロシージャーの外部にあると見なされます。
図 7 は、データ宣言の有効範囲を示しています。
左方の大括弧はブロック構造体を示しています。右方の大括弧は名前の各宣言の有効範囲を示しています。 Q と R の 2 つの宣言の有効範囲は、 Q と Q'、 および R と R' となっています。
X と Y は、 パッケージに包含されるすべてのプロシージャーにとって可視となっています。
図 8 は、入り口定数とステートメント・ラベルの宣言の有効範囲を示しています。
図 8 は、外部プロシージャーの A と E を 示しています。