Blocks and declaration parts
A block is a set of declarations followed by a compound statement. Programs, units’
implementation parts, procedures, functions and methods all have blocks.
The declaration parts are label, const, type,
var and, in Object Pascal, threadvar and
resourcestring, then procedure, function, constructor and destructor
declarations. ISO 7185 requires them in that order, once each; Turbo Pascal, Delphi and
Free Pascal allow them in any order and as often as needed.
label
label 10, Done;
begin
...
goto Done;
...
Done:
WriteLn('finished');
end.
Every label used by goto must be declared in the block it is in. A label
is an integer of up to four digits in ISO 7185, and an identifier in the other dialects.
A goto may not enter a structured statement; it may leave one, and ISO 7185
allows a jump from a nested procedure out to the block it is in. Free Pascal
allows such non-local jumps only with the nonlocalgoto mode switch, which
its macpas, iso and Extended Pascal modes turn on.
const
const
Max = 100; { untyped constant }
Pi2 = 2 * 3.14159; { a constant expression }
Name = 'Pascal';
Mask = [1, 3, 5]; { set constant }
Origin: TPoint = (X: 0; Y: 0); { typed constant, record }
Days: array[1..3] of string = ('Mon', 'Tue', 'Wed');
Version: string = 'v' + IntToStr(Max);
- An untyped constant takes its type from its value. Its value is computed at compile time from literals, other constants and a limited set of built-in functions (
Ord,Chr,Length,Low,High,SizeOf,Abs,Odd,Round,Truncand similar). - A typed constant (Turbo Pascal and later) is an initialised variable. Records are written
(X: 0; Y: 0), arrays(1, 2, 3), sets[…]and pointersnilor@Name. Whether a typed constant may be assigned to is set by{$J}({$WRITEABLECONST}); in Turbo Pascal it always could be. - Hint directives may follow a constant:
const Old = 1 deprecated 'use New';.
type
type
TColour = (Red, Green, Blue);
TIndex = 1..100;
TNames = array[TIndex] of string;
TPtr = ^TRecord;
TRecord = record Next: TPtr; end; { forward pointer reference }
TProc = procedure(N: Integer);
TClass = class of TObject;
TAlias = type Integer; { a distinct type }
A type declaration gives a name to a type. A pointer type may name a type that is declared
later in the same type part. The types are described on
Types.
var
var
I, J: Integer;
Name: string;
Table: array[1..10] of Real;
Count: Integer = 0; { initialised global variable (Delphi, Free Pascal) }
Screen: array[0..24, 0..79] of Word absolute $B800:0; { at a fixed address (Turbo Pascal) }
Alias: Integer absolute Count; { shares storage with another variable }
- A variable declaration lists names, a colon and a type. Variables declared at the top of a unit or program are global (static); those in a routine are local and live on the stack.
- A global variable may have an initial value. Local variables are not initialised, except that the compiler zeroes the reference-counted ones (strings, dynamic arrays, interfaces, variants).
absoluteplaces a variable at an address ($B800:0is the DOS segment:offset form) or on top of another variable.- Inline variables (Delphi 10.3 and later) are declared in the statements of a block:
var X := 5;,var Y: Integer;, and the loop variable offor var I := 0 to 9 do. Their scope runs to the end of the block, and the type may be inferred from the initial value. - In Delphi and Free Pascal a variable may also be declared
external(cvar; external;) to refer to a C variable.
threadvar
threadvar declares global variables of which each thread has its own copy.
The declaration syntax is that of var, and a threadvar may not be initialised.
Delphi and Free Pascal have it; Turbo Pascal and ISO Pascal do not.
resourcestring
resourcestring
SGreeting = 'Hello';
SFileMissing = 'File %s not found';
A resourcestring section declares string constants that are stored in the
program’s resource table, so they can be translated without changing the code. They are
used like string constants. Delphi and Free Pascal have them.
Scope and visibility
- A name is visible from its declaration to the end of its block, including nested blocks. A name declared in an inner block hides one with the same name in an outer block.
- A name declared in a unit’s
interfacepart is visible to every unit that uses it, and a name declared inimplementationonly in that unit. When two used units declare the same name, the one in the unit used last wins, and a qualified name (Unit2.Name) chooses. - A record’s or object’s field names are visible after the dot and inside a
withstatement. A method sees the fields of its object directly and throughSelf. - A name must be declared before it is used, with two exceptions: a pointer type’s target type, and a procedure that has an earlier
forwardheading. - A function’s name (or
Resultin Object Pascal modes) stands for its result inside the function.
Forward declarations
procedure B(N: Integer); forward;
procedure A(N: Integer);
begin
if N > 0 then B(N - 1);
end;
procedure B(N: Integer); { in Turbo Pascal the parameters may be left out here }
begin
if N > 0 then A(N - 1);
end;
A forward heading lets two routines call each other. In a unit, a heading in
the interface part is the forward declaration of the body in the
implementation part. Free Pascal’s repeatforward mode switch
requires the parameters to be repeated in the body, and the Delphi mode does not.
Hint directives
deprecated, experimental, platform and
library may follow a declaration (a unit, constant, type, variable, routine, class
member). The compiler then gives a warning or hint where the name is used.
deprecated may carry a message in quotes. unimplemented is Free
Pascal’s.
procedure Old; deprecated 'use New instead';
var X: Integer platform;
type TOld = class end experimental;