Next: , Previous: OOP, Up: Programming



6.9 Compiler Directives And The Preprocessor

GPC, like UCSD Pascal and BP, treats comments beginning with a $ immediately following the opening { or (* as a compiler directive. As in Borland Pascal, {$...} and (*$...*) are equivalent. When a single character plus a + or - follows, this is also called a compiler switch. All of these directives are case-insensitive (but some of them have case-sensitive arguments). Directives are local and can be changed during one compilation (except include files etc. where this makes no sense).

In general, compiler directives are compiler-dependent. (E.g., only the include directive {$I FileName} is common to UCSD and BP.) Because of BP's popularity, GPC supports all of BP's compiler directives (and ignores those that are unnecessary on its platforms – these are those not listed below), but it knows a lot more directives.

Some BP directives are – of course not by chance – just an alternative notation for C preprocessor directives. But there are differences: BP's conditional definitions ({$define Foo}) go into another name space than the program's definitions. Therefore you can define conditionals and check them via {$ifdef Foo}, but the program will not see them as an identifier Foo, so macros do not exist in Borland Pascal.

GPC does support macros, but disables this feature when the --no-macros option or the dialect option --borland-pascal or --delphi is given, to mimic BP's behaviour. Therefore, the following program will react differently when compiled with GPC either without special options or with, e.g., the --borland-pascal option (and in the latter case, it behaves the same as when compiled with BP).

     program MacroDemo;
     
     const Foo = 'Borland Pascal';
     
     {$define Foo 'Default'}
     
     begin
       WriteLn (Foo)
     end.

Of course, you should not rely on such constructs in your programs. To test if the program is compiled with GPC, you can test the __GPC__ conditional, and to test the dialect used in GPC, you can test the dialect, e.g., with {$ifopt borland-pascal}.

In general, almost every GPC specific command line option (see GPC Command Line Options) can be turned into a compiler directive (exceptions are those options that contain directory names, such as --unit-path, because they refer to the installation on a particular system, and therefore should be set system-wide, rather than in a source file):

     --foo       {$foo}
     --no-foo    {$no-foo}
     -Wbar       {$W bar}     { note the space after the W }
     -Wno-bar    {$W no-bar}

The following table lists some such examples as well as all those directives that do not correspond to command-line options or have syntactical alternatives (for convenience and/or BP compatibility).

     --[no-]short-circuit   $B+ $B- like in Borland Pascal:
                                    $B- means short-circuit Boolean
                                    operators; $B+ complete evaluation
     
     --[no-]io-checking     $I+ $I- like in Borland Pascal:
                                    enable/disable I/O checking
     
     --[no-]range-checking  $R+ $R- like in Borland Pascal:
                                    enable/disable range checking
     
     --[no-]stack-checking  $S+ $S- like in Borland Pascal:
                                    enable/disable stack checking
     
     --[no-]typed-address   $T+ $T- like in Borland Pascal:
                                    make the result of the address
                                    operator and the Addr function a
                                    typed or untyped pointer
     
     -W[no-]warnings        $W+ $W- enable/disable warnings. Note: in
                                    --borland-pascal mode, the
                                    short version is disabled because
                                    $W+/$W- has a different meaning in
                                    Borland Pascal (which can safely be
                                    ignored in GPC), but the long version
                                    is still available.
     
     --[no-]extended-syntax $X+ $X- mostly like in Borland Pascal:
                                    enable/disable extended syntax
                                    (ignore function resuls, operator
                                    definitions, PChar, pointer
                                    arithmetic, ...)
     
     --borland-pascal               disable or warn about GPC features
     --extended-pascal              not supported by the standard or
     --pascal-sc                    dialect given, do not warn about its
     etc.                           ``dangerous'' features (especially BP).
                                    The dialect can be changed during one
                                    compilation via directives like,
                                    e.g., {$borland-pascal}.
     
     {$M Hello!}                    write message Hello! to
                                    standard error during compilation. In
                                    --borland-pascal mode, it is
                                    ignored it if only numbers follow
                                    (for compatibility to Borland
                                    Pascal's memory directive)
     
     {$define FOO}                  like in Borland Pascal:
     or                             define FOO (for conditional compilation)
     {$CIDefine FOO}                (case-insensitively)
     
     --cidefine=FOO                 the same on the command line
     
     {$CSDefine FOO}                define FOO case-sensitively
     
     -D FOO                         the same on the command line
     or                             Note: --define on the command
     --csdefine=FOO                 line is case-sensitive like in GCC,
     or                             but {$define} in the source code
     --define=FOO                   is case-insensitive like in BP
     
     {$define loop while True do}   define loop to be while True do
     or                             as a macro like in C. The name of the
     {$CIDefine loop ...}           macro is case-insensitive. Note:
                                    Macros are disabled in
                                    --borland-pascal mode because BP
                                    doesn't support macros.
     
     --cidefine="loop=..."          the same on the command line
     
     {$CSDefine loop ...}           define a case-sensitive macro
     
     --csdefine="loop=..."          the same on the command line
     or
     --define="loop=..."
     
     {$I FileName}                  like in Borland Pascal:
                                    include filename.pas
                                    (the name is converted to lower case)
     
     {$undef FOO}                   like in Borland Pascal: undefine FOO
     
     {$ifdef FOO}                   conditional compilation
       ...                          (like in Borland Pascal).
     {$else}                        Note: GPC predefines the symbol
       ...                          __GPC__ (with two leading
     {$endif}                       and trailing underscores).
     
     {$include "filename.pas"}      include (case-sensitive)
     
     {$include <filename.pas>}      the same, but don't search in the
                                    current directory
...

and all the other C preprocessor directives.

You also can use the preprocessor directives in C style, e.g. #include, but this is deprecated because of possible confusion with Borland Pascal style #42 character constants. Besides, in the Pascal style, e.g. {$include "foo.bar"}, there may be more than one directive in the same line.