The INTERNAL and EXTERNAL attributes define the scope of a name.
>>-+-INTERNAL-----------------------------+-------------------->< '-EXTERNAL--+------------------------+-' '-(--environment-name--)-'
Abbreviations: INT for INTERNAL, EXT for EXTERNAL
When so specified, the name being declared effectively becomes internal and is not known outside of the compilation unit. The environment name is known instead.
The environment name must be a character string constant, and is used as is without any translation to uppercase.
dcl X entry external ('koala');
Environment names should not start with a break character (_). Names starting with this character are reserved for the library.
On platforms where the linker decorates environment names, if an environment name is specified with the external attribute, it will still be decorated if it differs only in case from the variable name. Consider the following declaration:
dcl abc ext('kLm'), xyz ext('xYz' );
The name for xyz is decorated. For more information about the decoration of environment names, see the "Understanding linkage considerations" topic in the "Calling conventions" chapter in the PL/I for Windows Programming Guide.
INTERNAL is the default for entry names of internal procedures and for all other variables except for entry constants, file constants and programmer defined conditions. INTERNAL specifies that the name can be known only in the declaring block. Any other explicit declaration of that name refers to a new object with a different scope that does not overlap.
EXTERNAL is the default for file constants, entry constants (other than internal procedures) and programmer-defined conditions. A name with the EXTERNAL attribute can be declared more than once, either in different external procedures or within blocks contained in external procedures. All declarations of the same name with the EXTERNAL attribute refer to the same data. The scope of each declaration of the name (with the EXTERNAL attribute) includes the scopes of all the declarations of that name (with EXTERNAL) within the application.
When a major structure or union name is declared EXTERNAL in more than one block, the attributes of the members must be the same in each case, although the corresponding member names need not be identical.
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;
If A.B is changed in ProcA, it is also changed for ProcB, and vice versa; if A.C is changed in ProcA, A.D is changed for ProcB, and vice versa.
Members of structures and unions always have the INTERNAL attribute.
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;
Note that, with no files specified in the GET and PUT statements, SYSIN and SYSPRINT are implicitly declared.