INTERNAL and EXTERNAL attributes
The INTERNAL and EXTERNAL attributes define the scope of a name.
Abbreviations: INT for INTERNAL, EXT for EXTERNAL
- environment-name
- Specifies the name by which the procedure or variable is known
outside of the compilation unit.
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.
See the following example: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
xyzis decorated. For more information about the decoration of environment names, see theUnderstanding linkage considerations
topic in theCalling 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.
Because external declarations for the same name all refer to the same data, they must all result in the same set of attributes. When EXTERNAL names are declared in different external procedures, the user has the responsibility to ensure that the attributes are matching. Example of scopes of various declarations illustrates a variety of declarations and their scopes.
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
Ais an external procedure name. Its scope is all of blockA, plus any other blocks whereAis declared as external.- 2
Sis explicitly declared in blockAand blockC. The character variable declaration applies to all of blockAexcept blockC. The fixed binary declaration applies only within blockC. Notice that althoughDis called from within blockC, the reference toSin the PUT statement inDis to the character variableS, and not to theSdeclared in blockC.- 3
Nappears as a parameter in blockD, but is also used outside the block. Its appearance as a parameter establishes an explicit declaration ofNwithinD. The references outsideDcause an implicit declaration ofNin blockA. These two declarations of the nameNrefer to different objects, although in this case, the objects have the same data attributes, which are, by default, FIXED BINARY(15,0) and INTERNAL. Under DEFAULT(ANS), the precision is (31,0).- 4
XandYare known throughoutBand can be referred to in blockCorDwithinB, but not in that part ofAoutsideB.- 5
PandQare parameters, and therefore if there were no other declaration of these names within the block, their appearance in the parameter list would be sufficient to constitute a contextual declaration. However, a separate, explicit declaration statement is required in order to specify thatPandQare arrays. Although the argumentsXandYare declared as arrays and are known in blockC, it is still necessary to declarePandQin a DECLARE statement to establish that they, too, are arrays. (The asterisk notation indicates that the bounds of the parameters are the same as the bounds of the arguments.)- 6
IandMare not explicitly declared in the external procedureA. Therefore, they are implicitly declared and are known throughoutA, even thoughIappears only within blockC.- 7
- The
OutandSetexternal procedures in the example have an external declaration ofLthat is common to both. They also must be declared explicitly with the ENTRY attribute in procedureA. Because ENTRY implies EXTERNAL, the two entry constantsSetandOutare known throughout the two external procedures. - 8
- The label
Bappears twice in the program—first inA, as the label of a begin-block, which is an explicit declaration, and then redeclared as a label within blockCby its appearance as a prefix to an END statement. Thego to Bstatement within blockC, therefore, refers to the label of the END statement within blockC. Outside blockC, any reference toBis to the label of the begin-block. - 9
BlocksCandDcan be called from any point withinBbut not from that part ofAoutsideB, nor from another external procedure. Similarly, because labelEis known throughout the external procedureA, a transfer toEcan be made from any point withinA. The labelBwithin blockC, however, can be referred to only from withinC. Transfers out of a block by a GO TO statement can be made; but such transfers into a nested block generally cannot. An exception is shown in the external procedureOut, where the labelEfrom blockCis passed as an argument to the label parameterR.Note that, with no files specified in the GET and PUT statements, SYSIN and SYSPRINT are implicitly declared.
- 10
- The statement
else go to R;transfers control to the labelE, even thoughEis declared withinA, and not known withinOut. - 11
- The variables
K(INTERNAL) andL(EXTERNAL) are declared as STATIC within theOutprocedure block; their values are preserved between calls toOut. - 12
- In order to identify the
Sin the procedureOutas the sameSin the procedureC, both are declared with the attribute EXTERNAL.
