Sign in Join
Wiki copytemporary

Enum type: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Enum type

OldNewLine
1+An **enumeration** is a custom [[Data type|data type]] in [[Pascal]]. It is a discrete value that can be referred to by a unique [[Identifier|identifier]].
2+
3+## Definition
4+
5+### Basic
6+
7+An enumeration is defined by surrounding a non-empty [[Comma|comma]]-separated list of identifiers that were not yet defined in the current [[Scope|scope]] with parentheses:
8+
9+``` pascal
10+program enumerationDemo(input, output, stdErr);
11+type
12+ fruit = (apple, banana, citrus);
13+```
14+
15+Thus, a variable of the [[Type|type]] `fruit` may assume the values `apple`, `banana`, or `citrus`.
16+
17+``` pascal
18+var
19+ snack: fruit;
20+begin
21+ snack := apple;
22+end.
23+```
24+
25+### Indices
26+
27+Every member of an enumerated type has an ordinal value which can be obtained using the [[Ord|standard function ord]]. The first member of any enumeration has the ordinal value zero, and every following member is enumerated with consecutive numbers.
28+
29+#### Override
30+
31+In some cases, however, it would be quite useful if the ordinal values were different. The [[FPC]] allows [[Delphi]]-style explicit definition of indices by following member identifiers with an [[=|equal sign]] and an [[Integer|integer]] value:
32+
33+``` pascal
34+type
35+ sign = (negative = -1, none = 0, positive = 1);
36+```
37+
38+It is not necessary to define *all* members with an explicit ordinal value, this example *just happens* to define all of them. If the ordinal value is unspecified, the automatic enumeration mechanism applies again.
39+
40+#### Properties
41+
42+- An enumeration data type definition is *ascending* if the difference in ordinal value to every right-hand member is ≥ 1. Currently, non-ascending definitions merely [emit a note](https://gitlab.com/freepascal.org/fpc/source/-/tree/release_3_2_2/compiler/ptype.pas#L1700-1706). A `set` literal using two enumeration values having the *same* ordinal value, albeit represented by *different* symbols, will not be accepted.
43+- An enumeration data type is *contiguous* if the ordinal value of every (named) member has an absolute difference of *one* to its neighbors. Using a `set` constructor on a non-contiguous enumeration data type may produce unexpected results.
44+- An enumeration data type is *normal* if it is ascending and contiguous and the first member has an ordinal value of (strictly speaking) *zero*, or, in the broad sense (as implemented by the FPC), ≤ 0. The compiler intrinsic `typeInfo` is *only* available for *those* enumeration data types.
45+
46+### Prefixing
47+
48+FPC prefixes all members of enumeration type definitions in the `type` section with their corresponding type name. By default, the short name *without* a prefix is inserted into the symbol table as an *alias* in order to meet Pascal standards.
49+
50+[[FPC New Features 2.6.0|Since version 2.6.0 FPC]] supports disabling member identifiers from being aliased by using the `{$scopedEnums on}` [[local compiler directives|local compiler directive]], thus requiring users to always specify the type name as a prefix:
51+
52+``` pascal
53+program scopedEnumerationDemo(input, output, stdErr);
54+type
55+ {$scopedEnums on}
56+ logLevel = (error, warning, info, debug);
57+var
58+ verbosity: logLevel;
59+begin
60+ verbosity := logLevel.debug;
61+end.
62+```
63+
64+This setting only affects definition of *new* enumeration data types. 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.`).
65+
66+This is useful if names are likely to clash with other identifiers, for example [`sysUtils.tUseBoolStrs`](https://www.freepascal.org/docs-html/rtl/sysutils/tuseboolstrs.html) is defined in that way (with `{$scopedEnums on}`), or if isolate identifiers would be meaningless or confusing like in [`objPas.tEndian`](https://www.freepascal.org/docs-html/rtl/objpas/tendian.html). Usage introduces some incompatibility to other compilers though.
67+
68+## Size
69+
70+The size an enumeration type occupies depends on
71+
72+1. the *minimum enumeration size* compiler configuration, and
73+2. the range, that is `ord(high(enumeration)) - ord(low(enumeration))`.
74+
75+The local compiler directive `{$minEnumSize n}` determines the minimum size in [[Byte|Bytes]] of an enumeration data type. `{$minEnumSize n}` is (for Delphi compatibility) an alias for `{$packEnum n}`/`{$Z}`.
76+
77+- `{$minEnumSize 1}`, `{$packEnum 1}`, `{$Z1}` or `{$Z‑}` instructs the compiler to use just one Byte (at least) for the enumeration type in question.
78+- `{$minEnumSize 2}`, `{$packEnum 2}` and `{$Z2}`: 2 Bytes minimum.
79+- `{$minEnumSize 4}`, `{$packEnum 4}`, `{$Z4}` or `{$Z+}`: use at least 4 Bytes.
80+
81+Furthermore, `{$minEnumSize normal}`, `{$minEnumSize default}` and `{$minEnumSize 0}` restores the default value. In [[Mode TP|{$mode TP}]] the default value is `1` whereas in all other modes it is `4`. Such a “large” minimum size aids quick read/write access.
82+
83+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. When there are 2<sup>8</sup> (256) or fewer elements to be stored, the compiler may store a variable of this kind as a single Byte. A range of 2<sup>16</sup> elements will be stored in two Bytes if a single Byte is insufficient. More than 2<sup>16</sup> members will be stored in four Bytes. These rules may, of course, be superseded by the previously mentioned `{$minEnumSize}` setting.
84+
85+## Application
86+
87+### Out-of-the-box functionality
88+
89+- The pre-defined data type [[Boolean]] is an enumeration data type.
90+- The functions `low` and `high` will give the lowest or highest available *named* item of an enumeration data type.
91+- The standard functions `pred` and `succ` return the predecessor and successor of a value. In non-Delphi modes this functionality is disabled if the enumeration data type is non-contiguous. Note that range checks may trigger [[runtime error|run-time errors]].
92+
93+### Masks
94+
95+Enumeration data types are particularly useful for implementing “masks”: By defining a [[Set|set of …]] you have a neat data type fulfilling certain nice properties.
96+
97+## Comparative remarks
98+
99+In some programming languages enumeration type definitions become “synonyms” to certain integer values. In Pascal, however, this is not the case. You may not mix a symbol referring to a member of an enumeration with other integer values. You will have to utilize `ord` or an [[Typecast|explicit typecast]] to the enumeration data type.
100+
101+## See also
102+
103+- [[Basic Pascal Tutorial/Chapter 5/Enumerated types|Enumerated types]] in the [[Basic Pascal Tutorial]] series
104+
105+---
106+*From the Free Pascal wiki, page "Enum type", as it stood on 2023-12-22 after a change by Alextpp, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history