Constants, Typed Constants & Variables
True constants have no storage; the compiler substitutes their values and can evaluate constant expressions using Ord, Chr, Length, SizeOf, Low, High, Trunc, Round, arithmetic, and more.
6.1 Constants
True constants have no storage; the compiler substitutes their values and can evaluate constant expressions using Ord, Chr, Length, SizeOf, Low, High, Trunc, Round, arithmetic, and more.
const
Pi2 = 2 * Pi; // constant expression
AppName = 'Inventory';
MaxUsers = 100;
Vowels = ['a', 'e', 'i', 'o', 'u']; // set constant
Debug = False;6.2 Typed constants
Typed constants are initialized variables with static storage. Whether they can be assigned is controlled by {$J} / {$WRITEABLECONST}:
FPC: writable by default ({$J+}).
Delphi: read-only by default ({$J-}) since Delphi 7.
A classic use of writable typed constants is a counter that keeps its value between calls:
Prefer a unit-level variable or a class variable in new code.
const
Primes: array[1..5] of Integer = (2, 3, 5, 7, 11);
Origin: record X, Y: Integer; end = (X: 0; Y: 0);
DefaultName: string = 'Guest';{$J+}
function NextId: Integer;
const
Counter: Integer = 0;
begin
Inc(Counter);
Result := Counter;
end;
{$J-}6.3 Resource strings
Stored as resources so they can be translated (Delphi ITE, Lazarus .po files).
resourcestring
SFileNotFound = 'File "%s" not found';6.4 Variables
Global variables (program or unit level) are zero-initialized.
Local variables are not initialized — except managed types (strings, dynamic arrays, interfaces, Variants), which start empty/nil.
Delphi 10.3+ supports inline variables with type inference (not supported by FPC):
var
Count: Integer;
Price, Tax: Double;
Name: string;
Done: Boolean = False; // initialized global variable (FPC and Delphi)// Delphi 10.3+ only
begin
var Total := 0; // inferred Integer
for var I := 1 to 10 do
Inc(Total, I);
const Msg = 'Sum: ';
Writeln(Msg, Total);
end;6.5 Absolute variables
var
B: Byte;
C: Char absolute B; // C shares B's memory (low-level trick; rarely needed)6.6 Scope
Identifiers declared in a block are visible from their declaration to the end of the block, including nested routines.
Inner declarations hide outer ones with the same name.
Unit interface declarations are visible to every unit that uses it.
Use the unit name to disambiguate: System.Writeln, MyUnit.Count.