Overview
Pascal is strongly typed. Every variable, constant and parameter has a type, which
is a name (a built-in or one declared with type) or a type expression
written in place. The types fall into simple types (ordinal and real), strings,
structured types, pointers, procedural types and, in Object Pascal, classes and
interfaces.
Ordinal types
An ordinal type has a first and a last value, and each value has a number and a
neighbour on each side. Ord, Succ, Pred,
Low and High work on them, and they may be array indexes,
case selectors, for loop variables and the base of a set.
Integer types
| Type | Range | Size |
|---|---|---|
ShortInt | −128 to 127 | 1 byte |
Byte | 0 to 255 | 1 byte |
SmallInt | −32768 to 32767 | 2 bytes |
Word | 0 to 65535 | 2 bytes |
LongInt | −2147483648 to 2147483647 | 4 bytes |
LongWord, DWord | 0 to 4294967295 | 4 bytes |
Int64 | −263 to 263−1 | 8 bytes |
QWord, UInt64 | 0 to 264−1 | 8 bytes |
Integer | the same as SmallInt in Turbo Pascal and in Free Pascal’s tp and fpc modes; LongInt in the Delphi and Object Pascal modes and in Delphi | 2 or 4 bytes |
Cardinal | the same as LongWord (Delphi, Free Pascal) | 4 bytes |
NativeInt, NativeUInt, PtrInt, PtrUInt, SizeInt, SizeUInt | as wide as a pointer | 4 or 8 bytes |
Int8 Int16 Int32 UInt8 UInt16 UInt32 | fixed-size aliases (Delphi, Free Pascal) | 1, 2, 4 bytes |
ISO 7185 has only integer, with a largest value maxint.
Turbo Pascal 1 to 3 had a 16-bit integer; Turbo Pascal 4 added
byte, word, shortint and longint;
Delphi 4 added int64.
Boolean types
Boolean (one byte, False = 0, True = 1; an
enumeration), and for Windows and C interfaces ByteBool,
WordBool, LongBool and QWordBool, where any non-zero value
counts as true and a result of True has all its bits set.
Character types
Char (one byte; in Delphi 2009 and later a 16-bit WideChar),
AnsiChar (one byte), WideChar (16-bit Unicode),
UnicodeChar, UCS4Char (32-bit). A one-character string
literal is a character. #65 and ^A are character constants.
Enumerations
type
TColour = (Red, Green, Blue);
TLevel = (Lo = 1, Mid = 5, Hi = 10); { values assigned: Delphi, Free Pascal }
TMode = (mdRead, mdWrite);
The values are numbered from zero, or from the assigned values, and the names are
constants. Ord(Blue) is 2. With {$SCOPEDENUMS ON} the names
must be written TColour.Red. An enumeration is one byte unless it has more
than 256 values or {$MINENUMSIZE} says otherwise.
Subranges
type
TDigit = 0..9;
TLetter = 'A'..'Z';
TMiddle = Green..Blue;
A subrange is a part of an ordinal type, given by its first and last constant. Range
checking ({$R+}) tests assignments to it.
Real types
| Type | Size | Notes |
|---|---|---|
Single | 4 bytes | IEEE 754 single |
Double | 8 bytes | IEEE 754 double |
Extended | 10 bytes (x87), 8 where there is no extended precision | 80-bit extended precision on Intel processors |
Real | 6 bytes in Turbo Pascal, 8 in Delphi and Free Pascal | Turbo Pascal’s own software format; in Delphi 4 and later a Double |
Real48 | 6 bytes | The old Turbo Pascal Real |
Comp | 8 bytes | A 64-bit integer stored in the coprocessor, counted as a real |
Currency | 8 bytes | A fixed-point number with four decimal places, scaled integer |
ISO 7185 has one type, real. Turbo Pascal’s coprocessor types are
single, double, extended and comp,
available with {$N+}.
String types
| Type | What it is |
|---|---|
string[N], ShortString | A length byte and up to N (at most 255) characters, indexed from 1. The string of Turbo Pascal, UCSD Pascal and Delphi 1. string without a size is string[255] when {$H-}. |
AnsiString | A reference-counted, dynamically sized string of 8-bit characters with a code page (Delphi 2 and later; Free Pascal). string is an AnsiString under {$H+}. |
UnicodeString | A reference-counted string of 16-bit UTF-16 characters (Delphi 2009 and later; Free Pascal). string is this in Delphi 2009 and later and in delphiunicode mode. |
WideString | A UTF-16 string managed by the Windows COM allocator; the Delphi type for OLE strings. |
UTF8String, RawByteString | An AnsiString in the UTF-8 code page, and one with no code page conversion. |
PChar, PAnsiChar, PWideChar | Pointers to zero-terminated character arrays, for C interfaces. |
packed array [1..N] of Char | The string type of ISO 7185, assigned from string literals of exactly that length. |
Strings are joined with + and compared with = and <
and the other operators. S[I] is character I (counting from 1, or from 0
with {$ZEROBASEDSTRINGS} in Delphi’s mobile compilers). Length,
SetLength, Copy, Pos, Delete and
Insert work on them (see Standard library).
Arrays
type
TRow = array[1..10] of Integer; { static, any ordinal index }
TGrid = array[0..7, 0..7] of Byte; { multi-dimensional }
TGrid2 = array[0..7] of array[0..7] of Byte; { the same, indexed a[i][j] }
TList = array of Integer; { dynamic, 0-based (Delphi 4, Free Pascal) }
TFlags = packed array[Boolean] of Byte; { packed; the index may be an enumeration }
procedure Sum(const A: array of Integer); { open array parameter }
procedure Show(const Args: array of const); { array of const: a list of values of any type }
- A static array has its bounds in the type. A dynamic array has them at run time:
SetLength(A, N)allocates,Length,HighandLowread it, and the memory is reference counted. - An open array parameter takes any array of that element type; inside the routine it runs from
0toHigh(A). array of constparameters holdTVarRecvalues and are written[1, 'two', 3.0]at the call (Formatuses them).packedremoves padding between the elements.bitpacked(Free Pascal) packs by bits.- Array constants are written with parentheses:
const Days: array[1..3] of String = ('Mon', 'Tue', 'Wed');.
Records
type
TPoint = record
X, Y: Integer;
end;
TShape = record
Name: string[20];
case Kind: (Circle, Rect) of { variant part: fields share storage }
Circle: (Radius: Real);
Rect: (Width, Height: Real);
end;
TPacked = packed record A: Byte; B: Word; end;
A record is a fixed set of named fields. Its variant part, begun by
case (with or without a tag field), overlays alternative field lists.
Turbo Pascal, Delphi and Free Pascal also allow methods, properties, operators and
constants in a record, and record helpers (see
Classes and objects). with
opens a record’s fields to a block of statements.
Sets
type
TLetters = set of 'A'..'Z';
TFlags = set of (Fast, Small, Safe);
var
F: TFlags;
begin
F := [Fast, Safe];
Include(F, Small);
if Fast in F then ...
end;
A set holds values of an ordinal base type with at most 256 values (ordinal values 0
to 255). The set constructor is a list in brackets, with ranges: [1, 3..5]. The operators are
+ union, - difference, * intersection, <= and
>= subset and superset, = and <>, and in
for membership. Free Pascal adds >< for the symmetric difference.
File types
var
T: Text; { text file }
R: file of TRecord; { typed file }
B: file; { untyped file: BlockRead, BlockWrite }
A file is a sequence of components of one type, accessed in order or, in the
non-standard dialects, by position. Text is a file of characters divided
into lines, with ReadLn and WriteLn. ISO 7185 files have a
buffer variable written F^ and the procedures get and
put; the other dialects use Read and Write on the
file. A file is bound to a name with Assign, opened with Reset,
Rewrite or Append and closed with Close
(assign is not in ISO 7185, where the program parameters are the file
names). TextFile is Delphi’s name for Text.
Pointer types
type
PNode = ^TNode;
TNode = record
Next: PNode; { a pointer may name a type declared after it }
Value: Integer;
end;
var
P: Pointer; { untyped pointer }
Q: PNode;
^T is a pointer to T; Q^ is the value it points at;
@X is the address of X; nil is the pointer to nothing.
Pointer is the untyped pointer. New and Dispose (and
GetMem, FreeMem) allocate and free the memory. In
Free Pascal and Delphi ({$POINTERMATH ON}) a typed pointer may be indexed and
added to like an array. ISO 7185 requires a pointer type to be declared as a name
of a type.
Procedural types
type
TCompare = function(A, B: Integer): Integer; { a plain routine }
TNotify = procedure(Sender: TObject) of object; { a method }
TAction = reference to procedure(X: Integer); { anonymous method (Delphi 2009) }
var
Callback: TCompare;
begin
Callback := @MyCompare; { Turbo Pascal and Free Pascal write @; Delphi mode takes the bare name }
WriteLn(Callback(1, 2));
end;
A procedural type describes a routine by its parameters and result. A variable of
such a type holds the address of a routine. of object adds the object the
method belongs to, making a method pointer (two pointers: the code and
Self). reference to accepts a routine, a method or an
anonymous method that captures variables. is nested is
Free Pascal’s form for a nested routine. Standard Pascal has procedural parameters but no variables of these types.
Variant types
Variant and OleVariant hold a value of any of many types
(integers, reals, strings, booleans, dates, arrays, IDispatch objects, empty and
null) and convert between them. VarType reports the current type,
VarIsNull and VarToStr read it. A variant is the usual way
to call COM automation objects late-bound. It is slower than a typed variable.
Classes, objects, interfaces
class, object (the old Turbo Pascal object), interface,
dispinterface, class references (class of T) and generic types are
described on Classes and objects and
Generics.
Declaring and aliasing types
type
TKey = Integer; { an alias: the same type }
TId = type Integer; { a new type with its own run-time type information; not compatible with Integer }
TName = string[40];
TRef = ^TName;
type before an existing type makes a distinct type (Delphi, Free Pascal), with
its own type information. TypeInfo(T) returns the run-time information, which
Delphi and Free Pascal use for published properties and streaming.
Type compatibility
- Two types are identical if they are the same name or aliases of it; two separate declarations of the same structure are not identical in ISO Pascal (the standard uses name equivalence).
- Assignments are allowed between assignment-compatible types: an integer subrange value to an integer type of enough range, an integer to a real, a character to a string, a string to a longer string, and so on. A range violation is an error at run time if range checking is on.
- Arithmetic on integers takes the larger type of the operands.
/always gives a real;divandmodwork on integers. - A type cast
T(X)reinterprets the value or the variable.Integer(Red),PChar(S),TFoo(Obj);asis the checked cast for classes and interfaces. varparameters need the identical type.