Enumerated Type

1. Enumerated Type

Pascal enums are well-encapsulated opaque types and used far more frequently in day-to-day development than enums from other programming languages.

Basic Declaration Syntax

type
  TAnimalKind = (akDuck, akCat, akDog);

Coding convention: Prefix enum constants with a two-letter shorthand of the type name

  • ak = Animal Kind (short form of TAnimalKind)
  • Purpose: Enum constants live in the unit’s global namespace by default. Adding prefixes drastically reduces naming collisions with other variables and custom types.

The leading T in TAnimalKind is optional syntax-wise, though it’s an industry standard. We recommend keeping it, as it makes it instantly clear the identifier represents an enum type.

type
  AnimalKind = (akDuck, akCat, akDog); // No leading T, valid syntaxCode language: JavaScript (javascript)

Additional Notes:

  1. Duplicate names won’t trigger compile errors; separate units may define identical identifiers;
  2. Still, proactively avoiding naming conflicts is advised for better readability and easier global text search (grep).

Scoped Enums ({$scopedenums on})

The compiler directive {$scopedenums on} encapsulates enum constants inside their parent type, preventing global namespace pollution

Disabled by Default
{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
program EnumDemo;

type TAnimalKind = (akDuck, akCat);

var k: TAnimalKind;

begin
  k := akDuck; // Direct constant access, no TAnimalKind. required
  WriteLn(k); // Output: akDuck
end.Code language: PHP (php)

As mentioned earlier, code execution starts from the begin keyword here.

Using the ak prefix is good practice to avoid clashes, though omitting it won’t break compilation.

{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}

program EnumDemo;

type TAnimalKind = (Duck, Cat);

var k: TAnimalKind;

begin
  k := Duck; 
  WriteLn(k);//Duck
end.Code language: PHP (php)

Mandatory Type Qualifier with {$scopedenums on}

  1. All references require a type qualifier: TAnimalKind.akDuck
  2. The ak prefix is no longer necessary; constants can be simplified to Duck, Cat, Dog
{$scopedenums on}
type
  TAnimalKind = (Duck, Cat, Dog);
var
  Kind: TAnimalKind;
begin
  Kind := TAnimalKind.Duck; // Type qualifier mandatory
end;Code language: PHP (php)

Omit the type qualifier as shown below

{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
{$scopedenums on}
program EnumDemo;

type TAnimalKind = (Duck, Cat);
var k: TAnimalKind;
begin
  k := Duck; // Missing TAnimalKind. qualifier
  WriteLn(k);
end.Code language: PHP (php)

Triggers a compilation error

D:\fpcdemo>fpc mydemo.dpr
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling mydemo.dpr
mydemo.dpr(9,8) Error: Identifier not found "Duck"
mydemo.dpr(11,4) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: C:\FPC\3.2.2\bin\i386-Win32\ppc386.exe returned an error exitcodeCode language: CSS (css)

Add the type qualifier as below

{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}
{$scopedenums on}
program EnumDemo;

type TAnimalKind = (Duck, Cat);
var k: TAnimalKind;
begin
  k := TAnimalKind.Duck; // Full type qualifier applied
  WriteLn(k);
end.Code language: PHP (php)

The code compiles without issues

Casting Between Enums and Integers

Enums count as opaque types; direct assignment between enums and integers is forbidden, explicit casting is required:

  1. Enum to Integer: Ord(EnumVariable)
  2. Integer to Enum: Explicit type cast TAnimalKind(IntegerValue)
  3. Always validate value range before casting integers to enums: valid range 0 ~ Ord(High(EnumType))
type
  TAnimalKind = (akDuck, akCat, akDog);
var
  Kind: TAnimalKind;
  Num: Integer;
begin
  Kind := akCat;
  Num := Ord(Kind); // akCat has ordinal index 1, Num=1

  Num := 2;
  // Validate range before casting
  if (Num >= 0) and (Num <= Ord(High(TAnimalKind))) then
    Kind := TAnimalKind(Num);
end;Code language: JavaScript (javascript)
{$ifdef FPC} {$mode objfpc} {$H+} {$endif}
{$codepage utf8}

program EnumDemo;

type
  TAnimalKind = (akDuck, akCat, akDog);
var
  Kind: TAnimalKind;
  Num: Integer;
begin
  Kind := akCat;
  Num := Ord(Kind); // akCat index is 1,Num=1

  Num := 2;

  if (Num >= 0) and (Num <= Ord(High(TAnimalKind))) then
    Kind := TAnimalKind(Num);

  WriteLn(Num);//2
end.Code language: PHP (php)

Enumeration

Leave a Reply

Your email address will not be published. Required fields are marked *