Go to the first, previous, next, last section, table of contents.


A QuickStart Guide from Borland Pascal to GNU Pascal.

This chapter is intended to be a QuickStart guide for programmers who are familiar with Borland Pascal.

Throughout the manual, we talk of "Borland Pascal" or "BP" for short, to refer to Borland Pascal version 7 for Dos protected mode. Other versions of Borland Pascal and Turbo Pascall don't differ too much, but this one was the very last Dos version Borland has published, so in most if not all cases, you can safely substitute the version you're familiar with.

"Borland Pascal" and "Turbo Pascal" are registered trademarks of Inprise Corp./Borland Inc.

BP Compatibility

GNU Pascal (GPC) is compatible to version 7 of Borland Pascal (BP) to a large extent and comes with portable replacements of the BP standard units.

However, BP is a 16-bit compiler while GPC is a 32/64-bit compiler, so the size of the `Integer' type, for instance, is 16 bits in BP, but at least 32 bits in GPC. If a BP program has been designed with portability in mind from the ground up, it may work with GPC without any change. Programs which rely on byte order, on the internals or sizes of data types or which use unportable things like interrupts and assembler code, will need to be changed. The following section lists the possible problems with solutions.

The GPC Run Time System (RTS) is fairly complete, and you can use all libraries written for GNU C from GNU Pascal, so there is much less need to use unportable constructs than there was in BP. (For example, BP's Turbo Vision library uses assembler to call a local procedure through a pointer. With GPC you can do this in Pascal just as with global procedures.) Please do not throw away the advantage of full portability by sticking to those workarounds.

We have successfully ported real-world projects (with several 10000s of lines) from BP to GPC, so this is possible for you, too.

BP Incompatibilities

This sections lists the remaining incompatibilities of GPC to BP, and the problems you might encounter when porting BP programs from 16-bit Dos to other platforms, and gives solutions for them.

By incompatibilites we mean problems that can arise when trying to compile a valid BP program with GPC. Of course, there are many features in GPC that BP doesn't know, but we call them extensions unless they can break valid BP programs, so they are not mentioned here. The subsequent sections of the `Borland Pascal' chapter mention a number of useful extensions that you might want to know about but which will not break your BP code.

Some of the differences can be "overcome" by command-line switches. As a summary:

--borland-pascal -w --uses=System -D__BP_TYPE_SIZES__ --pack-struct
-D__BP_RANDOM__ -D__BP_UNPORTABLE_ROUTINES__ -D__BP_PARAMSTR_0__

But please read the following notes, and don't use these switches indiscriminately when not necessary. There are reasons why they are not GPC's defaults.

String type

GPC's internal string format (Extended Pascal string schema) is different from BP's. BP compatible short strings will be implemented in GPC soon, but in the meantime, you'll have to live with the difference. In general, GPC's format has many advantages (no length limit of 255 characters, constant and reference parameters always know about their capacity, etc.), but you will see differences if you:

Qualified identifiers

GPC does not yet support qualified identifiers. They will be implemented soon. In the meantime, just don't use them, sorry. (In general, using the same global identifier in different units can easily be confusing, so it's not bad practice to avoid this, anyway.)

Assembler

GPC's inline assembler is not compatible to BP's. It uses AT&T syntax, supports a large variety of processors and works together with GPC's optimizer. So, either convert your inline assembly to AT&T syntax, or (usually better) to Pascal, or put it into an external file which you can assemble with your favourite (32 bit) assembler. A tutorial for using the GPC inline assembler is available at
ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/contrib/gpcasm.zip

Since many things you usually do with assembler in BP are provided by GPC's Run Time System (RTS), you will not need the inline assembler as often as in BP. (See section Portability hints.)

The same applies to BP's `inline' directive for hand-written machine code. GPC's `inline' directive works for Pascal routines (see section Miscellaneous), so you'll have to convert any hand-written machine code to Pascal (and thereby make it more readable, portable and easier to maintain while still getting the performance of inline code).

Move; FillChar

GPC supports `Move' and `FillChar', and they're fully BP compatible. However, some data structures have different internal formats which may become relevant when using these procedures. E.g., using `Move' on file variables does not work in GPC (there are reasons why assigning file variables with `:=' is not allowed in Pascal, and circumventing this restriction with `Move' is not a good idea). For other examples, see section String type, section Real type, and section Endianness assumptions.

Real type

GPC does not support BP's 6-byte `Real' type. It supports `Single', `Double' and `Extended' which, at least on the x86 and some other processors, are compatible to BP.

For BP's 6-byte `Real' type, GPC's `System' unit provides an emulation, called `BPReal', as well as conversion routines to GPC's `Real' type (which is the same as `Double'), called `RealToBPReal' and `BPRealToReal'. You'll probably only need them when reading or writing binary files containing values of the BP 6-byte real type. There are no operators (e.g., `+') available for `BPReal', but since GPC supports operator overloading, you could define them yourself (e.g., convert to `Real', do the operation, and convert back). Needless to say that this is very inefficient and should not be done for any serious computations. Better convert your data after reading them from the file and before writing them back, or simply convert your data files once (the other types are more efficient even with BP on any non-prehistoric processor, anyway).

Graph unit

A somewhat BP compatible Graph unit exists but is distributed separately due to its license. It is known to work under DJGPP and Linux/x86, under development under Mingw, and should work under any Unix system with X11 (but only tested on a few systems).

OOP units

The OOP stuff (Turbo Vision etc.) is not yet completed, but work on several projects is underway. If you want information about the current status or access to development source, please contact the GPC mailing list.

Keep; GetIntVec; SetIntVec

The routines `Keep', `GetIntVec' and `SetIntVec' in the `Dos' unit do not even make sense on DJGPP (32 bit Dos extender). If your program uses these, it is either a low-level Dos utility for which porting to a 32 bit environment might cause bigger problems (because the internal issues of DPMI become relevant which are usually hidden by DJGPP), or it installs interrupt handlers which will have to be thought about more carefully because of things like locking memory, knowing about and handling the differences between real and protected mode interrupts, etc. For these kinds of things, we refer you to the DJGPP FAQ (see section `DJGPP FAQ' in the DJGPP FAQ).

TFDDs

The internal structure of file variables (`FileRec' and `TextRec' in BP's `Dos' unit and `TFileRec' and `TTextRec' in BP's `WinDos' unit) is different in GPC. However, as far as Text File Device Drivers (TFDDs) are concerned, GPC offers a more powerful mechanism. Please see the RTS reference (see section Pascal declarations for GPC's Run Time System), under `AssignTFDD'.

Mem; Port; Ptr; Seg; Ofs; PrefixSeg; etc.

Those few routines in the `System' unit that deal with segmented pointers (e.g., `Ptr') are emulated in such a way that such ugly BP constructs like

PInteger (Ptr (Seg (a), Ofs (a) + 6 * SizeOf (Integer)))^ = 42

work in GPC, but they do not provide access to absolute memory addresses. Neither do `absolute' variables (which take a simple address in the program's address space in GPC, rather than a segmented address), and the `Mem' and `Port' arrays don't exist in GPC.

As a replacement for `Port' on x86 processors, you can use the routines provided in the `Ports' unit, section BP compatibility (partly): `Port', `PortW' arrays. If you want to access absolute memory addresses in the first megabyte under DJGPP, you can't do this with normal pointers because DJGPP programs run in a protected memory environment, unless you use a dirty trick called near pointer hack. Please see the DJGPP FAQ (see section `DJGPP FAQ' in the DJGPP FAQ) for this and for other ways.

For similar reasons, the variable `PrefixSeg' in the `System' unit is not supported. Apart from TSRs, its only meaningful use in BP might be the setting of environment variables. GPC provides the `SetEnv' and `UnSetEnv' procedures for this purpose which you can use instead of any BP equivalents based on `PrefixSeg'. (However note that they will modify the program's own and its childs' environment, not its parent's environment. This is a property -- most people call it a feature -- of the environments, including DJGPP, that GPC compiled programs run in.)

Endianness assumptions

GPC also runs on big-endian systems (see section Endianness). This is, of course, a feature of GPC, but might affect your programs when running on a big-endian system if they make assumptions about endianness, e.g., by using type casts (or `absolute' declarations or variant records misused as type casts) in certain ways. Please see the demo program `absdemo.pas' for an example and how to solve it.

Endianness is also relevant (the more common case) when exchanging data between different machines, e.g. via binary files or over a network. Since the latter is not easily possible in BP, and the techniques to solve the problems are mostly the same as for files, we concentrate on files here.

First, you have to choose the endianness to use for the file. Most known data formats have a specified endianness (usually that of the processor on which the format was originally created). If you define your own binary data format, you're free to choose the endianness to use.

Then, when reading or writing values larger than one byte from/to the file, you have to convert them. GPC's Run Time System supports this by some routines. E.g., you can read an array from a little-endian file with the procedure `BlockReadLittleEndian', or write one to a big-endian file with `BlockWriteBigEndian'. Note: The endianness in the procedure names refers to the file, not the system -- the routines know about the endianness of the system they run on, but you have to tell them the endianness of the file to use. This means you do not have to (and must not) use an `ifdef' to use the version matching the system's endianness.

When reading or writing records or other more complicated structures, either read/write them field by field using `BlockReadBigEndian' etc., or read/write them with the regular `BlockRead' and `BlockWrite' procedures and convert each field after reading or before writing using procedures like `ConvertFromBigEndian' or `ConvertToLittleEndian' (but remember, when writing, to undo the conversion afterwards, if you want to keep using the data -- this is not necessary with `BlockWriteLittleEndian' etc.).

Especially for strings, there are ready-made procedures like `ReadStringBigEndian' or `WriteStringLittleEndian' which will read/write the length as a 64 bit value (much space for really long strings :-) in the given endianness, followed by the characters (which have no endianness problem).

All these routines are described in detail in the RTS reference (see section Pascal declarations for GPC's Run Time System), under `endianness'. The demo program `endiandemo.pas' contains an example on how to use these routines.

- -borland-pascal - disable GPC extensions

GPC warns about some BP constructs which are especially "dirty", like misusing typed constants as initialized variables. GPC also supports some features that may conflict with BP code, like macros. The command line option `--borland-pascal' disables both, so you might want to use it for a first attempt to compile your BP code under GPC. However, we suggest you try compiling without this switch and fixing any resulting problems as soon as you've become acquainted with GPC.

-w - disable all warnings

Even in `--borland-pascal' mode, GPC may warn about some dangerous things. To disable all warnings, you can use the `-w' option (note: lower-case `w'!). This is not recommended at all, but you may consider it more BP compatible...

- -uses=System - Swap; HeapError; etc.

A few exotic BP routines and declarations (e.g., `Swap' and `HeapError') are contained in a `System' unit, section BP compatibility: System, which GPC (unlike BP) does not automatically use in each program. To use it, you can add a `uses System;' clause to your program. If you don't want to change your code, the command line option `--uses=System' will do the same.

-D__BP_TYPE_SIZES__ - small integer types etc.

Since GPC runs on 32 and 64 bit platforms, integer types have larger sizes than in BP. However, if you use the `System' unit (see section - -uses=System - Swap; HeapError; etc.) and define the symbol `__BP_TYPE_SIZES__' (by giving `-D__BP_TYPE_SIZES__' on the command line), it will redeclare the types to the sizes used by BP. This is less efficient and more limiting, but might be necessary if your program relies on the exact type sizes.

- -pack-struct - disable structure alignment

GPC by default aligns fields of records and arrays suitably for higher performance, while BP doesn't. If you don't want the alignment (e.g., because the program relies on the internal format of your structures), either declare the relevant structures as `packed' (which BP also accepts, but ignores), or give the `--pack-struct' option.

-D__BP_RANDOM__ - BP compatible pseudo random number generator

GPC uses a more elaborate pseudo random number generator than BP does. Using the `Random' and `Randomize' functions works the same way, but there is no `RandSeed' variable (but a `SeedRandom' procedure). However, if you use the `System' unit (see section - -uses=System - Swap; HeapError; etc.) and define the symbol `__BP_RANDOM__' (by giving `-D__BP_RANDOM__' on the command line), it will provide a 100% BP compatible pseudo random number generator, including the `RandSeed' variable, which will produce exactly the same sequence of pseudo random numbers that BP's pseudo random number generator does. Even the `Randomize' function will then behave exactly like in BP.

-D__BP_UNPORTABLE_ROUTINES__ - Intr; DosVersion; etc.

A few more routines in the `Dos' and `WinDos' units besides the ones mentioned under section Keep; GetIntVec; SetIntVec, like `Intr' or `DosVersion', are meaningless on non-Dos systems. By default, the `Dos' unit does not provide these routines (it only provides those that are meaningful on all systems, which are most of its routines, including the most commonly used ones). If you need the unportable ones, you get them by using the `System' unit (see section - -uses=System - Swap; HeapError; etc.) and defining the symbol `__BP_UNPORTABLE_ROUTINES__' (by giving `-D__BP_UNPORTABLE_ROUTINES__' on the command line). If you use `Intr' or `MsDos', your program will only compile under DJGPP then. Other routines, e.g. `DosVersion' are emulated quite roughly on other systems. Please see the notes in the `Dos' unit (see section BP compatibility: Dos) for details.

-D__BP_PARAMSTR_0__ - BP compatible ParamStr (0) behaviour

In BP (or under Dos), `ParamStr (0)' always contains the full path of the current executable. Under GPC, by default it contains what was passed by the caller as the 0th argument -- which is often the name of the executable, but that's merely a convention, and it usually does not include the path.

If you use the `System' unit (see section - -uses=System - Swap; HeapError; etc.) and define the symbol `__BP_PARAMSTR_0__' (by giving `-D__BP_PARAMSTR_0__' on the command line), it will change the value of `ParamStr (0)' to that of `ExecutablePath', overwriting the value actually passed by the caller, to imitate BP's/Dos's behaviour. However note: On most systems, `ExecutablePath' is not guaranteed to return the full path, so defining this symbol doesn't change anything. In general, you cannot expect to find the full executable path, so better don't even try it, or your program will (at best) run on some systems. For most cases where BP programs access their own executable, there are cleaner alternatives available.

IDE versus command line

On the Dos (DJGPP) and Linux platforms, you can use RHIDE for GNU Pascal; check the subdirectories of your DJGPP distribution.

Unfortunately, there is no IDE which would run on all platforms. We are working on it, but this will take some time. Please be patient -- or offer your help!

Without an IDE, the GNU Pascal Compiler, GPC, is called about like the command-line version of the Borland Pascal Compiler, BPC. Edit your source file(s) with your favorite ASCII editor, then call GNU Pascal with a command line like

C:\GNU-PAS> gpc hello.pas -o hello.exe

on your Dos or OS/2 box or

myhost:/home/joe/gnu-pascal> gpc hello.pas -o hello

on your Unix (or Unix-compatible) system.

Don't omit the `.pas' suffix: GPC is a common interface for a Pascal compiler, a C, ObjC and C++ compiler, an assembler, a linker, and perhaps an Ada and a FORTRAN compiler. From the extension of your source file GPC figures out which compiler to run. GPC recognizes Pascal sources by the extension `.pas', `.p', `.pp' or `.dpr'.

The -o is a command line option which tells GPC how the executable has to be named. If not given, the executable will be called `a.out' (Unix) or `a.exe' (Dos). However, you can use the `--executable-file-name' to tell GPC to always call the executable like the source (with the extension removed under Unix and changed to `.exe' under Dos).

Note that GPC is case-sensitive concerning file names and options, so it will not work if you type

C:\GNU-PAS> GPC HELLO.PAS -O HELLO.EXE

GPC is a very quiet compiler and doesn't print anything on the screen unless you request it or there is an error. If you want to see what is going on, invoke GPC with additional options:

-Q            "don't be quiet"  (or: Quassel-Modus in German)

(with capital `Q'!) means that GPC prints out the names of procedures and functions it processes, and

--verbose

or abbreviated

-v

means that GPC informs you about the stages of compilation, i.e. preprocessing, compiling, assembling, and linking.

One example (this time for OS/2):

[C:\GNU-Pascal] gpc --verbose -Q hello.pas

Throughout this chapter, we will tell you about a lot of command-line switches. They are all invoked this way.

After compilation, there will be an executable hello file in the current directory. (hello.exe on Dos or OS/2.) Just run it and enjoy. If you're new to Unix, please note that the current directory is not on the PATH in most installations, so you might have to run your program as `./hello'. This also helps to avoid name conflicts with other programs. Such conflicts are especially common with the program name `test' which happens to be a standard utility under Unix that does not print any output. If you call your program `test.pas', compile it, and then invoke `test', you will usually not run your program, but the utility which leads to mysterious problems. So, invoke your program as `./test' or, better yet, avoid the name `test' for your programs.

If there are compilation errors, GNU Pascal will not stop compilation after the first one -- as Borland Pascal does -- but try to catch all errors in one compilation. If you get more error messages than your screen can hold, you can catch them in a file (e.g. gpc.out) or pipe them to a program like `more' in the following way:

gpc hello.pas 2> gpc.out

This works with OS/2 and any bash-like shell under Unix; for Dos you must get a replacement for command.com which supports this kind of redirection, or use the `redir' utility (see also the DJGPP FAQ, section `DJGPP FAQ' in the DJGPP FAQ.):

C:\GNU-PAS> redir -eo gpc hello.pas -o hello.exe | more

You can also use Borland's IDE for GNU Pascal on the Dos platform: Install the GNU Pascal Compiler in the Tools menu (via Options/Tools).

Name:       GNU Pascal
Path:       gpc
Arguments:  $SAVE ALL --executable-file-name $NAME($EDNAME).pas
HotKey:     Shift+F9

Note once more that GPC is case-sensitive, so it is important to specify .pas instead of the .PAS Borland Pascal would append otherwise!

You can include more command-line arguments to GNU Pascal (e.g. `--automake'; see below) as you will learn more about them.

Since Borland Pascal will try to recompile your program if you use its Run menu function, you will need another tool to run your program:

Name:       Run Program
Path:       command.com
Arguments:  /c $NAME($EDNAME)
HotKey:     Shift+F10

Comments

GPC supports comments surrounded by `{ }' and `(* *)', just like BP does. According to the ISO 7185 and ISO 10206 standards, Pascal allows comments opened with (* and closed with }. Borland Pascal does not support such mixed comments, so you might have sources where passages containing comments are "commented out" using the other kind of comment delimiters. GPC's default behaviour is (like BP) not to allow mixed comments, so you don't need to worry about this. However, if you happen to like mixed comments, you can turn them on either by a command-line option, or by a compiler directive:

--mixed-comments     {$mixed-comments}    (*$mixed-comments*)

GPC supports nested comments (e.g., `{ foo { bar } baz }'), but they are disabled by default (compatible to BP which doesn't know nested comments at all). You can enable them with the option `--nested-comments' (or the equivalent compiler directive)

GPC also supports Delphi style comments starting with `//' and extending until the end of the line. This comment style is activated by default unless one of the `--standard-pascal', `--extended-pascal', `--object-pascal' or `--borland-pascal' dialect options is given. You can turn them on or off with the `--[no-]delphi-comments' option.

BP Compatible Compiler Directives

All of BP's one-letter compiler directives are supported by GPC, though some of them are ignored because they are not necessary under GPC. Besides, GPC supports a lot more directives. For an overview, see section Compiler Directives And The Preprocessor.

Units, GPI files and AutoMake

You can use units in the same way as in Borland Pascal. However, there are some additional features.

Concerning the syntax of a unit, you can, if you want, use Extended Pascal syntax to specify a unit initializer, i.e., instead of writing

begin
  ...
end.

at the end of the unit, you can get the same result with

to begin do
  begin
    ...
  end;

and there also exists

to end do
  begin
    ...
  end;

which specifies a finalization routine. You can use this instead of Borland Pascal's exit procedures, but for compatibility, the included `System' unit also provides the `ExitProc' variable. The `to begin do' and/or `to end do' parts must be followed by the final `end.'. See section The Source Structure of ISO-10206 Extended Pascal Modules, for information about Extended Pascal modules, an alternative to units.

When GPC compiles a unit, it produces two files: an .o object file (compatible with other GNU compilers such as GNU C) plus a .gpi file which describes the interface.

If you are interested in the internal format of GPI file, see section GPI files -- GNU Pascal Interfaces.

If you want to compile a program that uses units, you must "make" the project. (This is the command-line switch `-M' or the IDE keystroke `F9' in BP.) For this purpose, GPC provides the command-line switch `--automake':

gpc --automake hello.pas

If you want to force everything to be rebuilt rather than only recompile changed files (`-B' or "build" in BP), use `--autobuild' instead of `--automake':

gpc --autobuild hello.pas

For more information about the AutoMake mechanism, see section GPC's AutoMake Mechanism -- How it Works.

If you do not want to use the AutoMake mechanism for whatever reason, you can also compile every unit manually and then link everything together.

GPC does not automatically recognize that something is a unit and cannot be linked; you have to tell this by a command line switch:

-c            only compile, don't link.

(If you omit this switch when compiling a unit, you only get a linker error message `undefined reference to `main''. Nothing serious.)

For example, to compile two units, use:

gpc -c myunit1.pas myunit2.pas

When you have compiled all units, you can compile a program that uses them without using `--automake':

gpc hello.pas

However, using `--automake' is recommended, since it will recompile units that were modified.

You could also specify the program and the units in one command line:

gpc hello.pas myunit1.pas myunit2.pas

One of the purposes of writing units is to compile them separately. However, GNU Pascal allows you to have one or more units in the same source file (producing only one .o file but separate .gpi files). You even can have a program and one or more units in one source file; in this case, no .o file is produced at all.

Optimization

GNU Pascal is a 32/64 bit compiler with excellent optimization algorithms (which are identically the same as those of GNU C). There are six optimization levels, specified by the command line options `-O', `-O2', ..., `-O6'.

One example:

program OptimizationDemo;

procedure Foo;
var
  A, B : Integer;
begin
  A := 3;
  B := 4;
  WriteLn (A + B)
end;

begin
  Foo
end.

When GNU Pascal compiles this program with optimization (`-O3'), it recognizes that the argument to `WriteLn' is the constant 7 -- and optimizes away the variables A and B. If the variables were global, they would not be optimized away because they might be accessed from other places, but the constant 7 would still be optimized.

For more about optimization, see the GNU C documentation.

Debugging

The command line option `-g' specifies generation of debugging information for GDB, the GNU debugger. GDB comes with its own documentation. Currently, GDB does not understand Pascal syntax, so you should be familiar with C expressions if you want to use it.

See also "Notes for debugging" in the "Programming" chapter; see section Notes for Debugging.

Sometimes it is nice to have a look at the assembler output of the compiler. You can do this in a debugger or disassembler (which is the only way to do it in BP), but you can also tell GPC to produce assembler code directly: When you specify the -S command line option, GPC produces an .s file instead of an .o file. The .s file contains assembler source for your program. More about this in the next section.

Objects

Objects in the Borland Pascal 7.0 notation are implemented into GNU Pascal with the following differences:

Strings in BP and GPC

Strings are "Schema types" in GNU Pascal which is something more advanced than Borland-style strings. For variables, you cannot specify just String as a type like in Borland Pascal; for parameters and pointer types you can. There is no 255 characters length limit. According to Extended Pascal, the maximum string length must be in (parentheses); GNU Pascal accepts [brackets], too, however, like BP.

For more about strings and schema types see section EP's Schema Types including `String'.

GPC supports Borland Pascal's string handling functions and some more (see section String Operations):

  • Borland Pascal GNU Pascal
  • Length Length
  • Pos Pos, Index (1)
  • Str Str, WriteStr (1) (2)
  • Val Val, ReadStr (2)
  • Copy Copy, SubStr, MyStr [2 .. 7] (3)
  • Insert Insert
  • Delete Delete
  • MyStr [0] := #7 SetLength (MyStr, 7)
  • =, <>, <, <=, >, >= =, <>, <, <=, >, >= (4)
  • EQ, NE, LT, LE, GT, GE
  • n/a Trim Notes: (1) The order of parameters of the Extended Pascal routines (`Index', `WriteStr') is different from the Borland Pascal routines. (2) `ReadStr' and `WriteStr' allow an arbitrary number of arguments, and the arguments are not limited to numbers. `WriteStr' also allows comfortable formatting like `WriteLn' does, e.g. `WriteStr (Dest, Foo : 20, Bar, 1/3 : 10 : 2)'. (3) `SubStr' reports a runtime error if the requested substring does not fit in the given string, `Copy' does not (like in BP). (4) By default, the string operators behave like in BP. However, if you use the option `--no-exact-compare-strings' or `--extended-pascal', they ignore differences of trailing blanks, so, e.g., `'foo'' and `'foo '' are considered equal. The corresponding functions (`EQ', ...) always do exact comparisons.

    Typed Constants

    GNU Pascal supports Borland Pascal's "typed constants" but also Extended Pascal's initialized variables:

    var
      x : Integer value 7;
    

    or

    var
      x : Integer = 7;
    

    When a typed constant is misused as an initialized variable, a warning is given unless you specify `--borland-pascal'.

    When you want a local variable to preserve its value, define it as `static' instead of using a typed constant. Typed constants also become static automatically for Borland Pascal compatibility, but it's better not to rely on this "feature" in new programs. Initialized variables do not become static automatically.

    program StaticDemo;
    
    procedure Foo;
    { x keeps its value between two calls to this procedure }
    var
      x : static Integer = 0;
    begin
      WriteLn (x);
      Inc (x)
    end;
    
    begin
      Foo;
      Foo;
      Foo;
    end.
    

    For records and arrays, GPC supports both BP style and Extended Pascal style initializers. When you initialize a record, you may omit the field names. When you initialize an array, you may provide indices with a :. However, this additional information is ignored completely, so perhaps it's best for the moment to only provide the values ...

    program BPInitVarDemo;
    (*$W no-field-name-problem*) (* avoid a warning by GPC *)
    const
      A : Integer = 7;
      B : array [1 .. 3] of Char = ('F', 'o', 'o');
      C : array [1 .. 3] of Char = 'Bar';
      Foo : record
        x, y : Integer;
      end = (x : 3; y : 4);
    begin
    end.
    

    Bit, Byte and Memory Manipulation

    The bitwise operators `shl', `shr', `and', `or', `xor' and `not' work in GNU Pascal like in Borland Pascal. As an extension, you can use them as procedures, for example

    program AndProcedureDemo;
    var x : Integer;
    begin
      and (x, $0000ffff);
    end.
    

    as an alternative to

    program AndOperatorDemo;
    var x : Integer;
    begin
      x := x and $0000ffff;
    end.
    

    GPC accepts the BP style notation `$abcd' for hexadecimal numbers, but you also can use Extended Pascal notation:

    program EPBaseDemo;
    const
      Binary =  2#11111111;
      Octal  =  8#177;
      Hex    = 16#ff;
    begin
    end.
    

    and so on up to a basis of 36. Of course, you can mix the notations as you like, e.g.:

    program BPEPBaseDemo;
    begin
      WriteLn ($cafe = 2#1100101011111110)
    end.
    

    `Inc' and `Dec' are implemented like in Borland Pascal. `Pred' and `Succ' are generalized according to Extended Pascal and can have a second (optional) parameter:

    procedure SuccDemo;
    var a : Integer = 42;
    begin
      a := Succ (a, 5);
      WriteLn (a) { 47 }
    end.
    

    BP style `absolute' variables work in the context of overloading other variables as well as in the context of specifying an absolute address, but the latter is highly unportable and not very useful even in Dos protected mode.

    program BPAbsoluteDemo;
    
    type
      TString = String (80);
      TTypeChoice = (t_Integer, t_Char, t_String);
    
    (* WARNING: BAD STYLE! *)
    procedure ReadVar (var x : Void; TypeChoice : TTypeChoice);
    var
      xInt : Integer absolute x;
      xChar : Char absolute x;
      xStr : TString absolute x;
    begin
      case TypeChoice of
        t_Integer : ReadLn (xInt);
        t_Char    : ReadLn (xChar);
        t_String  : ReadLn (xStr);
      end
    end;
    
    var
      i : Integer;
      c : Char;
      s : TString;
    
    begin
      ReadVar (i, t_Integer);
      ReadVar (c, t_Char);
      ReadVar (s, t_String);
      WriteLn (i, ' ', c, ' ', s)
    end.
    

    GNU Pascal knows Borland Pascal's procedures FillChar and Move. However, their use can be dangerous because it often makes implicit unportable assumptions about type sizes, endianness, internal structures or similar things. Therefore, avoid them whenever possible. E.g., if you want to clear an array of strings, don't `FillChar' the whole array with zeros (this would overwrite the Schema discriminants, see section BP compatibility: Strings), but rather use a `for' loop to assign the empty string to each string. In fact, this is also more efficient than `FillChar', since it only has to set the length field of each string to zero.

    User-defined Operators in GPC

    GNU Pascal allows the user to define operators according to the Pascal-SC syntax:

    program PXSCOperatorDemo;
    
    type
      Point = record
        x, y : Real;
      end;
    
    operator + (a, b : Point) c : Point;
    begin
      c.x := a.x + b.x;
      c.y := a.y + b.y;
    end;
    
    var
      a, b, c : Point = (42, 0.5);
    
    begin
      c := a + b
    end.
    

    The Pascal-SC operators `+>', `+<', etc. for exact numerical calculations are not implemented, but you can define them.

    Data Types in BP and GPC

    BP Procedural Types

    In addition to BP's procedural types, GNU Pascal has pointers to procedures:

    type
      FuncPtr = ^function (Real) : Real;
    

    The differences between procedure pointers and procedural types are only syntactical:

    One can use both kinds in the same program, of course, though it is recommended to stick to one kind throughout to avoid maximum confusion.

    GNU Pascal also supports Standard Pascal's procedural parameters (see section Special Parameters).

    Furthermore, GNU Pascal allows you to call even local procedures through procedural pointers, variables or parameters without reverting to any dirty tricks (like assembler, which is necessary in BP).

    The differences between the various kinds of procedural types, pointers and parameters are demonstrated in the demo program `procvardemo.pas'. An example for calling local routines through procedural parameters can be found in the demo program `iteratordemo.pas'.

    Files

    Built-in Constants

    Built-in Operators in BP and GPC

    Besides the operators found in Borland Pascal, GNU Pascal supports the following operators:

    Built-in Procedures and Functions

    Special Parameters

    Miscellaneous

    BP and Extended Pascal

    Pascal is a well-known programming language and hardly needs to be described here. Note, however, that there is a large difference between the language used by the BP compiler and the Pascal Standards.

    Extended Pascal is a standardized language based on the original Standard Pascal, but with significant extensions. Unfortunately, Borland Pascal does not conform to any of the Pascal standards. Writing a program that both complies to Extended Pascal (or even Standard Pascal) and compiles with BP is almost impossible for any non-trivial task.

    On the other hand, BP has some nice features that make it very powerful in the environments in which it runs. However, some of those features are of little use on non-Dos systems and would not be good candidates for standardization.

    There are also several BP features which are semantically similar to features in Standard Pascal or Extended Pascal, but syntactically different.

    Therefore, in order to be useful to users coming from either side, GPC supports both the standards and the BP dialect as good as possible. By default, GPC allows features from any dialect it knows. By giving a dialect option such as `--borland-pascal' or `--extended-pascal', you can tell GPC to disable the features not found in that dialect, and to adjust its warning behaviour to the dialect.

    The different sets of reserved words are a little problem, but GPC solves it by making the words in question only "conditionally reserved" which works transparently without problems in most cases. Still, giving a dialect option will disable all keywords not part of this dialect.

    Apart from this, there are surprisingly few real conflicts between the dialects. Therefore, you can usually compile your BP code without the `--borland-pascal' option and make use of all of GPC's features. You might be surprised, though, when GPC accepts things you didn't know were allowed. :-)

    Finally, if you want to make use of some of GPC's extensions (compared to BP) and still keep the code compileable with BP without using `ifdef's all over the place, we suggest you look at the unit `gpc-bp.pas', shipped with GPC, which contains BP versions of some of GPC's features. Please read the comments at the beginning of the unit to find out more about it.

    Portability hints

    GPC offers you the possibility to make your code fully portable to each of the many platforms supported by GPC. It would be a pity not to make use of this.

    This section lists some known pitfalls that often hinder otherwise well-written programs to take full advantage of GPC. If you have never used any compiler but Borland Pascal and similar compilers, some of the advices might look strange to you. But this is just the same level of strangeness that your old programs will have for you once you have understood the principles of cross-platform portability. Remember that many tricks you have always been applying almost automatically in Borland Pascal were necessary to overcome certain limitations of the Dos platform and to compensate for the compiler's missing optimization. Programming with an optimizing compiler like GPC for platforms without a 64 kB limit is a completely new experience -- and perhaps it is among the reasons why you are now working with GPC in the first place?

    Portability -- why?

    Okay -- but why should I bother and make my program portable? I know that all who want to use my program are running WXYZ-OS anyway.

    Yes, but that's the result of a self-fulfilling prophecy. It depends on you whether it will always remain like this or not. Consider a program ABC written for a single platform, WXYZ-OS. Naturally, only WXYZ-OS-users get interested in ABC. The author gets feedback only from WXYZ-OS users and does not see any reason to make the program cross-platform. Then people realize that if they want to run ABC they must move to WXYZ-OS. The author concludes that people only want WXYZ-OS programs, and so on.

    To break out, just create a portable version of your program now. Then all OSes have equal chances to show their abilities when running your program, and your customers can choose their OS. Then, maybe, they decide to use your program just for the reason that they can be sure that it will run on all present and future platforms and not only on a specific one -- who knows?

    My program is a tool specifically designed to make the best of the STUV feature of WXYZ-OS. There is no point in making it portable.

    How much do you know about non-WXYZ-OSes? Just ask an expert how the STUV feature is named elsewhere. Be sure, if it is of value, it exists almost everywhere.

    Low-level features

    I am using a lot of low-level stuff in my programs, so they cannot be portable.

    You do not use those low-level routines directly in your high-level routines, do you? There should always be a layer "in-between" that encapsulates the low-level routines and present an API to your program that exactly reflects the needs of your application. This "API in between" is the point where you can exchange the low-level routines by portable calls to GPC's Run Time System.

    If you do not have such a layer in-between, then the API of the low-level routines you call are your first approximation for such a layer. If you have ever thought "it would be great if that API function had that additional parameter", then your own extended version of that API function that has that parameter can become part of your "API in between". But then don't stop here: Certainly the API of the OS is not ideal for your program's needs. Just create more routines that encapsulate all OS-specific stuff ...

    When the low-level stuff in question consists of interrupts, assembler and similar things, then the first thing you need is a portable replacement of the functionality. Fortunately, GPC covers many things already in Pascal that require assembler in Borland Pascal:


    Go to the first, previous, next, last section, table of contents.