Syntax
A compiler directive is a comment whose first character is $, followed
directly by a letter: {$R+}, {$mode objfpc},
(*$IFDEF DEBUG*). A comment that starts {$ and a space or
anything but a letter is an ordinary comment. The directive name does not depend on
case. A directive does not nest and ends at the first closing delimiter. A
// comment cannot hold a directive (Free Pascal warns about it).
Several switches can share one directive, separated by commas:
{$R+,Q+,S-}. Switches are on (+) or off
(-), and a long switch takes ON, OFF or
+, -: {$RANGECHECKS ON}.
Free Pascal divides directives into local directives, which affect the code
from that point on until changed (and can be saved with {$PUSH} and
restored with {$POP}), and global directives, which affect the
whole compilation and must come before the first declaration.
Compiler modes
{$MODE name} chooses the dialect the compiler accepts. It must come
before the first declaration, usually in the first lines.
| Mode | What it gives |
|---|---|
FPC | The default when no command line option is given: Free Pascal’s own dialect, close to Turbo Pascal 7 with its own extensions. Nested comments are on. |
OBJFPC | Object Pascal as Free Pascal does it (option -S2): classes, exceptions, properties, Result, generic and specialize. Nested comments are on. Strings stay short strings unless {$H+}. |
DELPHI | Delphi compatibility (-Sd): all Object Pascal extensions, and {$H ON} so that string is an AnsiString. Nested comments are off. |
DELPHIUNICODE | Delphi mode where string is a UnicodeString. |
TP | Turbo Pascal compatibility (-So): the Object Pascal extensions are off, except AnsiStrings, which stay valid. |
MACPAS | Mac Pascal: aims at the common Mac OS dialects (Think Pascal, Metrowerks Pascal, MPW Pascal). |
ISO | Standard Pascal of ISO 7185, levels 0 and 1. |
EXTENDEDPASCAL | Extended Pascal (ISO/IEC 10206), from Free Pascal 3.2. |
DEFAULT | Goes back to the mode of the command line. |
{$MODESWITCH name+} and {$MODESWITCH name-} turn single
features on and off. The names (Free Pascal 3.2.2) are:
ADVANCEDRECORDS (methods in records), ALLOWINLINE,
ANSISTRINGS, AUTODEREF (typed pointers dereference on their own),
CBLOCKS, CLASS, CLASSICPROCVARS,
CVAR, DEFAULTPARAMETERS, DUPLICATELOCALS,
EXCEPTIONS, HINTDIRECTIVE, INITFINAL,
ISOIO, ISOMOD, ISOPROGRAMPARAS,
ISOUNARYMINUS, MACPROCVARS, NESTEDCOMMENTS,
NESTEDPROCVARS, NONLOCALGOTO, OBJECTIVEC1,
OBJECTIVEC2, OBJPAS, OUT,
PCHARTOSTRING, POINTERTOPROCVAR, PROPERTIES,
REPEATFORWARD, RESULT, SYSTEMCODEPAGE,
TYPEHELPERS and UNICODESTRINGS. The development version
adds more, among them MULTILINESTRINGS,
UNDERSCOREISSEPARATOR, ANONYMOUSFUNCTIONS,
FUNCTIONREFERENCES, ARRAYOPERATORS, PREFIXEDATTRIBUTES
and STATEMENTEXPRESSIONS, REORDEREDOPERATORS and TYPEINQUIRY, as the compiler source shows.
Switches
The single-letter switches come from Turbo Pascal. Each has a long name in Free Pascal and Delphi.
| Directive | Long name | Meaning |
|---|---|---|
{$A}, {$A1 $A2 $A4 $A8} | ALIGN | Alignment of data (Turbo Pascal: word alignment on or off) |
{$B} | BOOLEVAL | Complete evaluation of boolean expressions (off: short-circuit) |
{$C} | ASSERTIONS | Whether assert generates code (Turbo Pascal 7: the segment attribute of code) |
{$D} | DEBUGINFO | Debugging symbols |
{$E} | (emulation) | Floating point emulation (Turbo Pascal) |
{$F} | (far) | Far or near calls (Turbo Pascal and other 16-bit) |
{$G} | 80286 code | |
{$H} | LONGSTRINGS | string is an AnsiString (on) or a short string (off) |
{$I} | IOCHECKS | Input/output error checking ({$I+} raises an error, {$I-} sets IOResult) |
{$I file} | INCLUDE | Include a file |
{$J} | WRITEABLECONST | Typed constants may be assigned to |
{$L file} | LINK | Link an object file (as a switch, LOCALSYMBOLS in Delphi) |
{$M} | TYPEINFO or MEMORY | Generate run-time type information, or set stack and heap sizes (Turbo Pascal) |
{$N} | (numeric) | Numeric coprocessor (Turbo Pascal) |
{$O} | Level 2 optimisations (as a switch) | |
{$P} | OPENSTRINGS | Open string parameters |
{$Q} | OVERFLOWCHECKS or OV | Integer overflow checking |
{$R} | RANGECHECKS | Range checking of array indexes and subranges |
{$R file} | RESOURCE | Link a resource file |
{$S} | STACKCHECKS | Stack checking |
{$T} | TYPEDADDRESS | Typed @ operator |
{$V} | VARSTRINGCHECKS | Strict checking of var string parameters |
{$W} | STACKFRAMES | Stack frames for every routine |
{$X} | EXTENDEDSYNTAX | Function calls may be statements, PChar rules |
{$Y} | REFERENCEINFO | Browser (symbol reference) information |
{$Z}, {$Z1 $Z2 $Z4} | PACKENUM or MINENUMSIZE | Minimum size of an enumeration |
Free Pascal directives
The Programmer’s guide (3.2.2) lists these. The local directives:
ALIGN A1 A2 A4 A8 ASMMODE (the assembler syntax: intel, att or direct), ASSERTIONS BITPACKING
(packing by bits), BOOLEVAL CALLING (the default calling convention),
CHECKPOINTER CODEALIGN COPERATORS (the += family),
DEFINE DEFINEC ELSE ELSEC ELSEIF ELIFC ENDC ENDIF ENDREGION ERROR ERRORC EXTENDEDSYM
EXTERNALSYM F FATAL FPUTYPE GOTO H HINT HINTS HPPEMIT IF IFC IFDEF IFNDEF IFOPT
IMPLICITEXCEPTIONS INFO INLINE INTERFACES I IOCHECKS IEEEERRORS INCLUDE J WRITEABLECONST L LINK
LIBEXPORT LINKFRAMEWORK LINKLIB M TYPEINFO MACRO MAXFPUREGISTERS MESSAGE MINENUMSIZE
MINFPCONSTPREC MMX NODEFINE NOTE NOTES OBJECTCHECKS OPTIMIZATION PACKENUM PACKRECORDS
PACKSET POP PUSH Q OV OVERFLOWCHECKS R RANGECHECKS REGION RESOURCE SATURATION
SAFEFPUEXCEPTIONS SCOPEDENUMS SETC S STOP STRINGCHECKS T TYPEDADDRESS UNDEF UNDEFC V
VARSTRINGCHECKS W STACKFRAMES WAIT WARN WARNING WARNINGS Z1 Z2 Z4. The global
directives:
APPID APPNAME APPTYPE (GUI, CONSOLE), CODEPAGE (the source
code page), COPYRIGHT D DEBUGINFO DESCRIPTION E EXTENSION FRAMEWORKPATH G IMAGEBASE
INCLUDEPATH L LOCALSYMBOLS LIBPREFIX LIBRARYPATH LIBSUFFIX MAXSTACKSIZE M MEMORY
MINSTACKSIZE MODE MODESWITCH N O OBJECTPATH P OPENSTRINGS PASCALMAINNAME PIC POINTERMATH
PROFILE SCREENNAME SETPEFLAGS SMARTLINK SYSCALLS THREADNAME UNITPATH VARPROPSETTER VERSION
WEAKPACKAGEUNIT X EXTENDEDSYNTAX Y REFERENCEINFO.
Some of these exist only so that Delphi source compiles, and are ignored:
EXTENDEDSYM, EXTERNALSYM, HPPEMIT,
LIBEXPORT, NODEFINE, STRINGCHECKS and
WEAKPACKAGEUNIT.
Delphi directives
Delphi has most of the switches above, and these of its own (from the Delphi
documentation as remembered; DocWiki was not read here): {$IF expression},
{$ELSEIF}, {$IFEND} and {$LEGACYIFEND} (see
below), {$ALIGN}, {$APPTYPE}, {$DEFINITIONINFO},
{$DENYPACKAGEUNIT}, {$DESIGNONLY}, {$RUNONLY},
{$EXCESSPRECISION}, {$HIGHCHARUNICODE},
{$IMPORTEDDATA}, {$LIBSUFFIX}, {$OBJEXPORTALL},
{$POINTERMATH}, {$REALCOMPATIBILITY}, {$RTTI},
{$SCOPEDENUMS}, {$STRONGLINKTYPES}, {$WEAKLINKRTTI},
{$WARN id ON|OFF|ERROR|DEFAULT} and {$ZEROBASEDSTRINGS}.
Conditional compilation
| Directive | Meaning |
|---|---|
{$DEFINE NAME}, {$UNDEF NAME} | Define or undefine a symbol. DEFINEC, UNDEFC are the same in the C style. |
{$IFDEF NAME}, {$IFNDEF NAME} | The code that follows is compiled if the symbol is (is not) defined. |
{$IF expression}, {$IFC expression} | Compiled if a compile-time expression is true. Free Pascal and Delphi 6 and later. The expression may use Defined(NAME), Declared(name), comparison and boolean operators, and the compile-time variables and constants. |
{$IFOPT R+} | Compiled if a switch has the given state. |
{$ELSE}, {$ELSEC}, {$ELSEIF expression}, {$ELIFC} | The other branch. |
{$ENDIF}, {$ENDC}, {$IFEND} | The end of the conditional. Delphi closes an {$IF} with {$IFEND} (and with {$ENDIF} under {$LEGACYIFEND ON}). |
{$SETC NAME := expression} | Define a compile-time variable. |
Symbols come from {$DEFINE}, from the command line (-dNAME) and from the
compiler. Free Pascal predefines symbols for the compiler (FPC), its version
(VER3, VER3_2, VER3_2_2), the processor (CPU386, CPUX86_64,
CPUAARCH64 and others), the operating system (LINUX, WINDOWS,
DARWIN, UNIX), the byte order (ENDIAN_LITTLE, ENDIAN_BIG) and
the features (FPC_HAS_FEATURE_*); the Programmer’s guide lists them in its
“Predefined symbols” section. Delphi defines VERnnn for each release,
MSWINDOWS, CPUX64, UNICODE and CONDITIONALEXPRESSIONS, and the constants
CompilerVersion and RTLVersion that an {$IF} expression can compare.
{$IFDEF FPC}
{$mode objfpc}{$H+}
{$ENDIF}
{$IF Defined(MSWINDOWS) or Defined(WINDOWS)}
uses Windows;
{$ELSE}
uses BaseUnix;
{$ENDIF}
{$IFOPT R+}
{ range checks are on }
{$ENDIF}
Code in a branch that is switched off is skipped by the compiler, so it need not be valid, but it must still tokenise: an unfinished comment or a stray quote can end the skipped text early.
Macros, messages and compiler information
{$MACRO ON}then{$DEFINE NAME := text}defines a macro whose name, when it appears in the source, is replaced by the text (Free Pascal).{$MACRO OFF}turns it off.{$MESSAGE text},{$HINT text},{$NOTE text},{$INFO text},{$WARNING text},{$ERROR text},{$FATAL text}and{$STOP text}print a message while compiling; the last three stop the compile.{$WAIT}waits for a key.{$I %NAME%}inserts compiler information as a string, such as%DATE%,%TIME%,%FILE%,%LINE%,%FPCVERSION%,%FPCTARGET%,%FPCTARGETOS%and%FPCTARGETCPU%.{$WARN name ON|OFF},{$HINTS ON|OFF},{$NOTES}and{$WARNINGS}control which messages appear.{$REGION 'name'}and{$ENDREGION}mark a collapsible region for the editor.
Include files, linking and resources
{$I file}or{$INCLUDE file}reads another file at that point.{$INCLUDEPATH dir}sets where Free Pascal looks.{$R file}or{$RESOURCE file}links a resource file (.res);{$R *.dfm}and{$R *.res}use the name of the current unit or program. Free Pascal and Lazarus can also turn the resource into an include with{$I unit1.lrs}.{$L file.o}or{$LINK file.o}links an object file forexternalroutines.{$LINKLIB name}links a library,{$LINKFRAMEWORK name}a macOS framework.{$UNITPATH},{$OBJECTPATH},{$LIBRARYPATH}and{$FRAMEWORKPATH}add to the search paths.