Modern Pascal Built-in Data Types
Built-in Data types (aka Primitive Types) of an entity (for example variables and constants) define the meaning, constraints, and possible values, along with functionality and mode of storage associated with it. Integer, Float (a.k.a. Real or Fractions), Boolean and Character types are referred to as Standard Types or Native Types. Data types can be categorized as Scalar, Pointer and Structured data types. All type identifiers scope doesn't include itself except for pointer and class types. The following data types are built-in and are also known as primitives.
Scalar Standard
- Integer
- Float
- Character
- Boolean
Scalar User Defined
- Enumerated (Enumerators)
- Sub-Range
Pointer
- Pointer
Structured
- Array
- Record
- Set
Integer types
Pronounced /in-tij-er/ is a noun, means a whole number; a number that is not a fraction. In Modern Pascal, there are 4 sizes of integer, 8bit, 16bit, 32bit and 64bit used to hold whole number values from the subrange minimum to the maximums below:
Type | Minimum | Maximum | Format | Bytes |
Byte | 0 | 255 | unsigned 8-bit | 1-byte |
UInt8 | 0 | 255 | unsigned 8-bit | 1-byte |
Shortint | -128 | 127 | signed 8-bit | 1-byte |
Int8 | -128 | 127 | signed 8-bit | 1-byte |
Word | 0 | 65,535 | unsigned 16-bit | 2-byte |
UInt16 | 0 | 65,535 | unsigned 16-bit | 2-byte |
Smallint | -32,768 | 32,767 | signed 16-bit | 2-byte |
Int16 | -32,768 | 32,767 | signed 16-bit | 2-byte |
Cardinal | 0 | 4,294,967,295 | unsigned 32-bit | 4-byte |
LongWord | 0 | 4,294,967,295 | unsigned 32-bit | 4-byte |
UInt32 | 0 | 4,294,967,295 | unsigned 32-bit | 4-byte |
Integer | -2,147,483,648 | 2,147,483,647 | signed 32-bit | 4-byte |
Longint | -2,147,483,648 | 2,147,483,647 | signed 32-bit | 4-byte |
Int32 | -2,147,483,648 | 2,147,483,647 | signed 32-bit | 4-byte |
LargeWord | 0 | 18,446,744,073,709,551,615 | unsigned 64-bit | 8-byte |
UInt64 | 0 | 18,446,744,073,709,551,615 | unsigned 64-bit | 8-byte |
LargeInt | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 | signed 64-bit | 8-byte |
Int64 | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 | signed 64-bit | 8-byte |
Float types
Short for floating-point notation, denotes a mode of representing numbers as two sequences of bits, one representing the whole number and the other determines the fraction. A value's floating-point notation normally comprises three values-M, B, and E-such that M x BE = N, where B is always 2, and both M and E are integral values within the float type's range. These M and E values further prescribe the float type's range and precision. In Modern Pascal, there are 3 sizes of float, 4byte, 8byte and 10byte used to hold number values from the minimum to the maximums below:
Type | Minimum | Maximum | Significant Digits | Format |
Single | 1.5E-45 | 3.4E38 | 7 to 8 places | 4-byte |
Double | 5.0E-324 | 1.7E308 | 15 to 16 places | 8-byte |
Extended | 1.9E-4932 | 1.1E4932 | 19 to 20 places | 10-byte |
Currency | -922337203685477.5808 | 922337203685477.5807 | 19 to 20 places | 8-byte |
Character types
Char's set of values are characters, ordered according to the extended's ASCII character set. The function call Ord(Ch), where Ch is a Char value, returns Ch's ordinality. A string constant of length 1 can denote a constant character value. Any character value can be generated with the standard function Chr. In Modern Pascal, there are 3 distinct types of character types, single, wide and unicode. There are two distinct versions of these 3 times, single and multiple character collections or strings.
Type | Minimum | Maximum | Format |
AnsiChar | #0 | #255 | 1-byte |
Char | #0 | #255 | 1-byte |
WideChar | #0#0 | #255#255 | 2-byte UTF-16 |
UnicodeChar | #0#0 | |
2-byte Limited |
AnsiString | #0 | #255 | 0-byte to 255-bytes |
String | #0 | #255 | 0-byte to 4 Gig |
WideString | #0#0 | #255#255 | 0-byte to 4 Gig |
UnicodeString | #0#0 | |
0-byte to 4 Gig |
PAnsiChar | #0 | #255 | Unlimited |
PChar | #0#0 | #255#255 | Unlimited |
PWideChar | #0#0 | #255#255 | Unlimited |
Boolean types
There are four predefined Boolean types: Boolean, ByteBool, WordBool, and LongBool. Boolean values are denoted by the predefined constant identifiers False and True. They are different memory sizes for memory alignment, but contain true and false, or 0 for false and non-zero for true.
Boolean and ByteBool variables occupy one byte, a WordBool variable occupies two bytes (one word), and a LongBool variable occupies four bytes (two words). Boolean is the preferred type and uses the least memory; ByteBool, WordBool, and LongBool exist primarily to provide compatibility with other languages and the Windows environment.
A Boolean variable can assume the ordinal values a and 1 only, but variables of type ByteBool, WordBool, and LongBool can assume other ordinal values. An expression of type ByteBool, WordBool, or LongBool is considered False when its ordinal value is zero, and True when its ordinal value is nonzero. Whenever a ByteBool, WordBool, or LongBool value is used in a context where a Boolean value is expected, the compiler will automatically generate code that converts any nonzero value to the value True.
Type | Minimum | Maximum | Ord(True) | Format |
Boolean | False | True | Any non-zero | 1-byte |
ByteBool | False | True | Any non-zero | 1-byte |
WordBool | False | True | Any non-zero | 2-byte |
LongBool | False | True | Any non-zero | 4-byte |
Enumerated types
In Modern Pascal enumerated types are a special way of creating your own variable types. Enumerated types define ordered sets of values by enumerating the identifiers that denote these values. Their ordering follows the sequence the identifiers are enumerated in.
Type | Enumerators |
Direction | (North, East, South, West) |
Days | (monday, tuesday, wednesday, thursday, friday, saturday, sunday) |
Subrange types
In Modern Pascal subrange types are a range values from an ordinal type. A subrange type is a range of values from an ordinal type called the host type. The definition of a subrange type specifies the smallest and the largest value in the subrange. To define a subrange type, you must specify its limiting values, minimum to maximum. Subrange types can also be of the above enumeration types. To avoid errors you should initialize a variable of Range type to it's default, the compiler does not do this.
Type | Range |
Longint | -$80000000..$7FFFFFFF |
Byte | 0..255 |
WeekDays | monday..friday |
WeekEnd | saturday..sunday |
Pointer type
In Modern Pascal a variable of the pointer type references an address in memory, where the data of another variable may be stored. Pointers are a type, which means that they point to a particular kind of data. From a character type, to a structured record type and even an instance of an object structure or class type.
Type | Of | Syntax(es) |
Pointer | any address and size in memory | GetMem(Var,2048), Var:=AllocMem(2048) |
^Type | Type, used for heap allocation of instance of type | New(Var) |
Instance | of a class | Var.Init; |
Structured types
A structured type is a type that can hold multiple values in one variable. Structured types can be nested to unlimited levels.
Types |
array type |
record type |
class type |
set type |
Static Arrays
Static Arrays have a fixed number of components of one type, the component type. Static arrays are predefined number of elements of a specified type. Modern Pascal supports multidimensional arrays written in long form. The component type follows the word of.
Static Array | Multidimensional Static Array |
Var A:Array [0..6] of Integer; | Var A:Array [0..6] of Array[0..9] of Integer; |
Var S:Array [1..5] of String; | Var S:Array [1..5] of Array[1..3] of String; |
Const Pass=5; Fail=3; | |
Var Points:Array[Fail..Pass] of Integer; | Var A:Array[0..6] of Array[0..4] of Array[0..9] of Integer; |
Dynamic Arrays
Dynamic Arrays are similar to static arrays as far a the component type, however, they are useful when you do not know the upper limit in advance. Using the SetLength() command you can dynamically increase and decrease the size of the zero based array.
Dynamic Array | Multidimensional Dynamic Array |
Var A:Array of Integer; | Var A:Array of Array of Integer; |
Var S:Array of String; | Var S:Array of Array of String; |
SetLength(A,10); | SetLength(A,10); SetLength(A[0],10); |
SetLength(S,10); | SetLength(S,10); SetLength(S[0],10); |
Pre-Defined Dynamic Array Aliases
Functions cannot return the definition array of type, however, these predefined type aliases can be returned as function results.
Defined Array Type | Equivalent Dynamic Array Definition |
TBooleanArray; | Array of Boolean; |
TByteBoolArray; | Array of ByteBool; |
TWordBoolArray; | Array of WordBool; |
TLongBoolArray; | Array of LongBool; |
TByteArray; | Array of Byte; |
TCharArray; | Array of Char; |
TWideCharArray; | Array of WideChar; |
TUnicodeCharArray; | Array of UnicodeChar; |
TWordArray; | Array of Word; |
TSmallIntArray; | Array of SmallInt; |
TLongWordArray; | Array of LongWord; |
TIntegerArray; | Array of Integer; |
TLongIntArray; | Array of LongInt; |
TLargeWordArray; | Array of LargeWord; |
TLargeIntArray; | Array of LargeInt; |
TInt64Array; | Array of Int64; |
TSingleArray; | Array of Single; |
TDoubleArray; | Array of Double; |
TExtendedArray; | Array of Extended; |
TCurrencyArray; | Array of Currency; |
TStringArray; | Array of String; |
Record Types
Records are the complementary structure to an array. Where an array is a collection of like types, record types can be a collection of many different data types. Of course, you can also have an array of your record type. Records provide a well organized way of managing groups of data fields. A few data types are added as pointers (4 or 8 byte addresses) to the actual data, for example a record with an element of the type String will show sizeof(record_type) of either 4 or 8 (depending upon 32bit or 64bit platforms). This is important to remember when you store and retrieve records with these types - you will lose the data. You can avoid this issue by using string[84]; for example to store length byte 84 characters, which is much like using the type array[0..84] of char; where the 0th byte you put in a char(length).
Modern Pascal supports fixed records and records with variant parts. The variant part must be the last element in the record definition. The optional identifier in the union statement serves to access the variant field value, which otherwise would be invisible to the programmer. It can be used to see which variant is active at a certain time. In effect, it introduces a new field in the record.
By default, Modern Pascal will align each element on either 4 byte or 8 byte addresses in memory to achieve optimal access for performance. However, you may want to store these records to disk for example, and to reduce unnecessary padding to disk you can use the keyword Packed Record instead of Record to define no alignment.
program HelloRecordWorld; uses display; type UserRec=Record Name:String[55]; PwrdSHA1:String[40]; Verified:Boolean; Age:Byte; End; StoredUserRec=Packed Record Name:String[55]; PwrdSHA1:String[40]; Verified:Boolean; Age:Byte; End; (* Here the main program block starts *) begin WriteLn('Unpacked used ',SizeOf(UserRec),' bytes.'); // displays 102 WriteLn('Packed used ',SizeOf(StoredUserRec),' bytes.');// displays 99 Readkey; end.
Set Types
Modern Pascal supports the set types as defined years ago in Turbo Pascal. Each of the elements of the set's type must be of the target type. Where Target type can be any ordinal type with a range between 0 (zero) and 255. A set can contain at most 255 elements. Sets are another way in which Pascal is unique from other languages. Whereas, enumerated types allow a variable to have one and only one value at a time, sets allow you to have any combination of given values. None, One, Multiples or All.
A set therefore holds a set of indicators, again up to 255 indicators (or elements). At first this may sound a little tricky to understand, however, it may help if you think of sets as a dynamic array of the elements from an enumerated type, and a boolean of true it is in this set or false it is not.
program HelloSetWorld; uses display; type Days=(Sun=0, Mon, Tue, Wed, Thr, Fri, Sat); DaysWorked=Set of Days; var Schedule:DaysWorked; begin Schedule:=[Mon, Wed, Thr, Fri]; Writeln('This week I work 9-5 on ',Schedule); Schedule+=[Tue]; Schedule-=[Thr]; Writeln('Next week I work 9-5 on ',Schedule); ReadKey; end.