3.1.1 Ordinal types

With the exception of int64, qword and Real types, all base types are ordinal types. Ordinal types have the following characteristics:

  1. Ordinal types are countable and ordered, i.e. it is, in principle, possible to start counting them one bye one, in a specied order. This property allows the operation of functions as Inc (??), Ord (??), Dec (??) on ordinal types to be dened.
  2. Ordinal values have a smallest possible value. Trying to apply the Pred (??) function on the smallest possible value will generate a range check error if range checking is enabled.
  3. Ordinal values have a largest possible value. Trying to apply the Succ (??) function on the largest possible value will generate a range check error if range checking is enabled.

Integers

A list of pre-dened integer types is presented in table (3.1)


Table 3.1: Predened integer types

Name
Integer
Shortint
SmallInt
Longint
Longword
Int64
Byte
Word
Cardinal
QWord
Boolean
ByteBool
LongBool
Char

The integer types, and their ranges and sizes, that are predened in Free Pascal are listed in table (3.2). It is to note that the qword and int64 types are not true ordinals, so some pascal constructs will not work with these two integer types.


Table 3.2: Predened integer types

Type Range Size in bytes
Byte 0 .. 255 1
Shortint -128 .. 127 1
Smallint -32768 .. 32767 2
Word 0 .. 65535 2
Integer either smallint, longint or int64 size 2,4 or 8
Cardinal either word, longword or qword size 2,4 or 8
Longint -2147483648 .. 2147483647 4
Longword 0..4294967295 4
Int64 -9223372036854775808 .. 9223372036854775807 8
QWord 0 .. 18446744073709551615 8

The integer type maps to the smallint type in the default Free Pascal mode. It maps to either a longint or int64 in either Delphi or ObjFPC mode. The cardinal type is currently always mapped to the longword type. The denition of the cardinal and integer types may change from one architecture to another and from one compiler mode to another. They usually have the same size as the underlying target architecture.

Free Pascal does automatic type conversion in expressions where dierent kinds of integer types are used.

Boolean types

Free Pascal supports the Boolean type, with its two pre-dened possible values True and False. It also supports the ByteBool, WordBool and LongBool types. These are the only two values that can be assigned to a Boolean type. Of course, any expression that resolves to a boolean value, can also be assigned to a boolean type.


Table 3.3: Boolean types

Name SizeOrd(True)
Boolean 1 1
ByteBool 1 Any nonzero value
WordBool2 Any nonzero value
LongBool 4 Any nonzero value

Assuming B to be of type Boolean, the following are valid assignments:

 B := True;  
 B := False;  
 B := 1<>2;  { Results in B := True }

Boolean expressions are also used in conditions.

Remark: In Free Pascal, boolean expressions are always evaluated in such a way that when the result is known, the rest of the expression will no longer be evaluated (Called short-cut evaluation). In the following example, the function Func will never be called, which may have strange side-eects.

 ...  
 B := False;  
 A := B and Func;

Here Func is a function which returns a Boolean type.

Enumeration types

Enumeration types are supported in Free Pascal. On top of the Turbo Pascal implementation, Free Pascal allows also a C-style extension of the enumeration type, where a value is assigned to a particular element of the enumeration list.

_________________________________________________________________________________________________________ Enumerated types
-- --enumerated type (----|-identi  er list----) ----------------------
                       6-assigned enum list-- |
                       --------, ---------

-- --identi  er list-identi  er ------------------------------------------
                 6---,----

-- --assigned enum list---identi  er-:=- expression ------------------------
                     6----------,-----------|
___________________________________________________________________

(see chapter 8, page 250 for how to use expressions) When using assigned enumerated types, the assigned elements must be in ascending numerical order in the list, or the compiler will complain. The expressions used in assigned enumerated elements must be known at compile time. So the following is a correct enumerated type declaration:

Type  
  Direction = ( North, East, South, West );

The C style enumeration type looks as follows:

Type  
  EnumType = (one, two, three, forty := 40,fortyone);

As a result, the ordinal number of forty is 40, and not 3, as it would be when the ':= 40' wasn't present. The ordinal value of fortyone is then 41, and not 4, as it would be when the assignment wasn't present. After an assignment in an enumerated denition the compiler adds 1 to the assigned value to assign to the next enumerated value. When specifying such an enumeration type, it is important to keep in mind that the enumerated elements should be kept in ascending order. The following will produce a compiler error:

Type  
  EnumType = (one, two, three, forty := 40, thirty := 30);

It is necessary to keep forty and thirty in the correct order. When using enumeration types it is important to keep the following points in mind:

  1. The Pred and Succ functions cannot be used on this kind of enumeration types. Trying to do this anyhow will result in a compiler error.
  2. Enumeration types stored using a default size. This behaviour can be changed with the f$PACKENUM ng compiler directive, which tells the compiler the minimal number of bytes to be used for enumeration types. For instance
    Type  
    {$PACKENUM 4}  
      LargeEnum = ( BigOne, BigTwo, BigThree );  
    {$PACKENUM 1}  
      SmallEnum = ( one, two, three );  
    Var S : SmallEnum;  
        L : LargeEnum;  
    begin  
      WriteLn ('Small enum : ',SizeOf(S));  
      WriteLn ('Large enum : ',SizeOf(L));  
    end.

    will, when run, print the following:

    Small enum : 1  
    Large enum : 4

More information can be found in the Programmers guide, in the compiler directives section.

Subrange types

A subrange type is a range of values from an ordinal type (the host type). To dene a subrange type, one must specify it's limiting values: the highest and lowest value of the type.

_________________________________________________________________________________________________________ Subrange types
-- --subrange type-constant ..- constant--------------------------------
___________________________________________________________________

Some of the predened integer types are dened as subrange types:

Type  
  Longint  = $80000000..$7fffffff;  
  Integer  = -32768..32767;  
  shortint = -128..127;  
  byte     = 0..255;  
  Word     = 0..65535;

Subrange types of enumeration types can also be dened:

Type  
  Days = (monday,tuesday,wednesday,thursday,friday,  
          saturday,sunday);  
  WorkDays = monday .. friday;  
  WeekEnd = Saturday .. Sunday;