Enum type

From Free Pascal wiki
Revision as of 07:09, 31 July 2020 by Kai Burghardt (talk | contribs) (rewrite)
Jump to navigationJump to search

English (en)

An enumeration is a custom data type in Pascal. It is a discrete value that can be referred to by a unique identifier.

Definition

Basic

An enumeration is defined by surrounding a non-empty comma-separated list of (previously unknown) identifiers with parentheses:

1program enumerationDemo(input, output, stdErr);
2type
3	fruit = (apple, banana, citrus);

Thus, a variable of the type fruit may assume the values apple, banana, or citrus.

4var
5	snack: fruit;
6begin
7	snack := apple;
8end.

Indices

Every member of an enumerated type has an ordinal value which can be obtained using the standard function ord. The first member of any enumeration has the ordinal value zero, and every following member are enumerated with consecutive numbers.

In some cases, however, it would be quite useful if the ordinal values were different. FPC allows Delphi-style explicit definition of indices by following member identifiers with an equal sign and an integer value:

type
	sign = (negative = -1, none = 0, positive = 1);

All values must be ascending order. Note, it is not necessary to define all members with an explicit ordinal value, this example just happens to define all of them. You may skip giving individual members an explicit index, however, the automatic continuous numbering must not clash with the indices provided.

Instead of a single = FPC also allows :=.

Prefixing

FPC supports automatic prefixing of member identifiers with data type’s name by using the {$scopedEnums on} local compiler directive. By default this is off.

program scopedEnumerationDemo(input, output, stdErr);
type
	{$scopedEnums on}
	logLevel = (error, warning, info, debug);
var
	verbosity: logLevel;
begin
	verbosity := logLevel.debug;
end.

If the compiler switch {$scopedEnums …} was on during definition of a enumeration type, you have to precede any values of that enumeration type with the data type’s name and a dot (in the example above this means logLevel.).

Size

The size an enumeration type occupies depends on

  1. the minimum enumeration size compiler configuration, and
  2. the range, that is ord(high(enumeration)) - ord(low(enumeration)).

The local compiler directive {$minEnumSize n} determines the minimum size in Bytes of an enumeration data type. {$minEnumSize n} is (for Delphi compatibility) an alias for {$packEnum n}/{$Z}.

  • {$minEnumSize 1}, {$packEnum 1}, {$Z1} or {$Z off}instruct the compiler to use just at least one Byte for the enumeration type in question.
  • {$minEnumSize 2}, {$packEnum 2} and {$Z2}: 2 Bytes minimum.
  • {$minEnumSize 4}, {$packEnum 4}, {$Z4} or {$Z on}: use at least 4 Bytes.

Furthermore, {$minEnumSize normal}, {$minEnumSize default} and {$minEnumSize 0} restore the default value. In {$mode TP} the default value is 1 whereas in all other modes it is 4. Such a “large” minimum size aides quick read/write access.

It stands to reason that an enumeration data type has to occupy at least as much space as all discrete values require to be stored. If less or equal to 28 (256) elements have to be storable, the compiler may store a variable of this kind as a single Byte. A range of 216 elements will be stored in two Bytes if not in one Byte suffices. More than 216 members are stored in four Bytes. These rules may, of course, be superseded by the previously mentioned {$minEnumSize} setting.

Application

Out-of-box functionality

The standard functions pred and succ will return the predecessor and successor of a value. Note that range checks may trigger run-time errors.

The pre-defined data type Boolean is an enumeration data type.

The functions low and high will give the lowest or highest available named item of an enumeration data type.

Masks

Enumeration data types are particularly useful for implementing “masks”: By defining a set of  you have a neat data type fulfilling certain nice properties.

See also