228
FREE PASCAL MANUALS User's guide . Programmer's guide . Reference guide for the system unit, and supported Pascal constructs. Standard units reference manual .

Free Pascal Manual

Embed Size (px)

Citation preview

Page 1: Free Pascal Manual

FREE PASCAL MANUALS

User's guide . Programmer's guide . Reference guide for the system unit,

and supported Pascal constructs. Standard units reference manual .

Page 2: Free Pascal Manual

Free Pascal :Users' manual

Contents Introduction About this document About the compiler Getting more information. Installing the compiler Before Installation : Requirements Installing the compiler. Testing the compiler Compiler usage Compiling a program Compiling a unit Creating an executable for GO32V1 and PMODE/DJ targets Reducing the size of your program Compiling problems General problems Problems you may encounter under DOS Compiler configuration Using the command-line options Using the configuration file Porting Turbo Pascal Code Things that will not work Things which are extra Turbo Pascal compatibility mode Utilities and units that come with Free Pascal Supplied programs Supplied units Debugging your Programs Compiling your program with debugger support Using gdb to debug your program Caveats when debugging with gdb Support for gprof , the gnu profiler CGI programming in Free Pascal Getting your data Producing output I'm under Windows, what now ? Alphabetical listing of command-line options Alphabetical list of reserved words Compiler error messages Compiler errors Run time errors Assembler reader errors. The Floating Point Coprocessor emulator A sample gdb.ini file

Page 2 Free Pascal Manual

Page 3: Free Pascal Manual

INTRODUCTION

About this document About the compiler Getting more information.

ABOUT THIS DOCUMENT

This is the user's manual for Free Pascal . It describes the installation and use of the Free Pascal compiler on the different supported platforms. It does not attempt to give an exhaustive list of all supported commands, nor a definition of the Pascal language. Look at the Reference guide for these things. For a description of the possibilities and the inner workings of the compiler, see the Programmer's guideİn the appendices of this document you will find lists of reserved words and compiler error messages (with descriptions). This document describes the compiler as it is/functions at the time of writing. Since the compiler is under continuous development, some of the things described here may be outdated. In case of doubt, consult the README files, distributed with the compiler. The README files are, in case of conflict with this manual, authoritative.

ABOUT THE COMPILER

Free Pascal is a 32-bit compiler for the i386 and m68k processors. Currently, it supports 2 operating systems:

DOS LINUX

and work is in progress to port it to other platforms (notably, OS/2 and WINDOWSNT). Free Pascal is designed to be, as much as possible, source compatible with Turbo Pascal 7.0 and Delphi II (although this goal is not yet attained), but it also enhances these languages with elements like function overloading. And, unlike these ancestors, it supports multiple platforms. It also differs from them in the sense that you cannot use compiled units from one system for the other. Also, at the time of writing, there is no Integrated Development Environment (IDE) available for Free Pascal. This gap will, hopefully, be filled in the future. Free Pascal consists of three parts :

1. The compiler program itself.2. The Run-Time Library (RTL).3. Utility programs and units.

Of these you only need the first two, in order to be able to use the compiler. In this document, we describe the use of the compiler. The RTL is described in the Reference guide.

GETTING MORE INFORMATION.

If the documentation doesn't give an answer to your questions, you can obtain more information on the Internet, on the following addresses:

http://tfdec1.fys.kuleuven.ac.be/michael/fpk.htm contains information on the LINUX port of the compiler. It contains also useful mail addresses and links to other places.

http://www.brain.uni-freiburg.de/klaus/fpk-pas is the main Free Pascal information site. It also contains the instructions for inscribing to the mailing-list, another useful source of information.

Both places can be used to download the Free Pascal distribution, although you can probably find them on other places also. Finally, if you think something should be added to this manual (entirely possible), please do not hesitate and contact me at [email protected] .

Free Pascal Manual Page 3

Page 4: Free Pascal Manual

Let's get on with something useful.

Page 4 Free Pascal Manual

Page 5: Free Pascal Manual

INSTALLING THE COMPILER 

Before Installation : Requirements Installing the compiler. Testing the compiler

BEFORE INSTALLATION : REQUIREMENTS

System requirements

The compiler needs at least the following hardware: 1. An I386 or higher processor. A coprocessor is not required, although it will slow down your

program's performance if you do floating point calculations.2. 2 Mb of free memory. Under DOS, if you use DPMI memory management, such as under

Windows, you will need at least 8 Mb.3. At least 500 Kb. free disk space.

Software requirements

UNDER DOS

The DOS distribution contains all the files you need to run the compiler and compile pascal programs.

UNDER LINUX

Under LINUX you need to have the following programs installed : 1. gnu as, the gnu assembler.2. gnu ld, the gnu linker.3. Optionally (but highly recommended) : gnu make. For easy recompiling of the compiler and

Run-Time Library, this is needed. Other than that, Free Pascal should run on almost any I386 LINUX system.

INSTALLING THE COMPILER.

The installation of Free Pascal is easy, but is platform-dependent. We discuss the process for each platform separately.

Installing under DOS

MANDATORY INSTALLATION STEPS.

First, you must get the latest distribution files of Free Pascal. They come as zip files, which you must unzip first. The distribution zip file contains an installation program INSTALL.EXE. You must run this program to install the compiler. The program allows you to select:

What components you wish to install. (e.g do you want the sources or not, do you want docs or not) Items that you didn't download will not be enabled, i.e. you can't select them.

Where you want to install (the default location is C:\PP).

Free Pascal Manual Page 5

Page 6: Free Pascal Manual

The installation program generates a batch file which sets some environment variables : SET_PP.BAT. This file is located in the directory where you installed Free Pascal. The installation program doesn't modify the AUTOEXEC.BAT, since many people (including the authors of Free Pascal) don't like this. You can choose to insert a call to this batch file in your AUTOEXEC.BAT file, like this : CALL C:\PP\SET_PP.BAT(This is assuming that you installed Free Pascal in the default location.) In order to run Free Pascal from any directory on your system, you must extend your path variable to contain the C:\PP\BIN directory. You can choose to do this in your AUTOEXEC.BAT file, but you can also insert a statement in the SET_PP.BAT file. Whatever the location you choose, It should look something like this : SET PATH=%PATH%;C:\PP\BIN(Again, assuming that you installed in the default location). If you want to use the graphic drivers you must modify the environment variable GO32. Instructions for doing this can be found in the documentation of the Graph unit, at the InitGraph procedure.

OPTIONAL INSTALLATION: THE COPROCESSOR EMULATION

For people who have an older CPU type, without math coprocessor (i387) it is necessary to install a coprocessor emulation, since Free Pascal uses the coprocessor to do all floating point operations. The installation of the coprocessor emulation is handled by the installation program (INSTALL.EXE). However, the installation program has currently a bug: If you select the coprocessor emulation the program ignores this and you must do this by hand. You should change the GO32 environment variable in the SET_PP.BAT file, as follows: SET GO32=emu C:\PP\DRIVERS\EMU387

Installing under Linux

MANDATORY INSTALLATION STEPS.

The LINUX distribution of Free Pascal comes in three forms: a tar.gz version, a .rpm (Red Hat Package Manager) version, and a .deb (debian) version.

All of these packages contain a ELF version of the compiler binaries and units. the older aout binaries are no longer distributed, although you still can use the comiler on an aout system if you recompile it. If you use the .rpm format, installation is limited to rpm -i fpc-pascal-XXX.rpm(XXX is the version number of the .rpm file) If you use debian, installation is limited to dpkg -i fpc-XXX.debHere again, XXX is the version number of the .deb file. You need root access to install these packages. The .tar file allows you to do an installation if you don't have root permissions. When downloading the .tar file, installation is more interactive: This means that you should first untar the file, in some directory where you have write permission, using the following command: tar -xvf fpc.tarWe supposed here that you downloaded the file fpc.tar somewhere from the Internet. (The real filename will have some version number in it, which we omit here for clarity.) When the file is untarred, you will be left with more archive files, and an install program: an installation shell script. To install Free Pascal, all that you need to do now is give the following command: ./install.shAnd then you must answer some questions. They're very simple, they're mainly concerned with 2 things :

1. Places where you can install different things.

Page 6 Free Pascal Manual

Page 7: Free Pascal Manual

2. Deciding if you want to install certain components (such as sources and demo programs). If you run the installation script as the root user, you can just accept all installation defaults. If you don't run as root, you must take care to supply the installation program with directory names where you have write permission, as it will attempt to create the directories you specify. In principle, you can install it wherever you want, though. At the end of installation, the installation program will generate a configuration file for the Free Pascal compiler which reflects the settings that you chose. It will install this file in the /etc directory, (if you are not installing as root, this will fail), and in the directory where you installed the libraries. If you want the Free Pascal compiler to use this configuration file, it must be present in /etc, or you can set the environment variable PPC_CONFIG_PATH. Under csh, you can do this by adding a setenv PPC_CONFIG_PATH /usr/lib/ppc/0.99.1line to your .login file in your home directory. (see also the next section)

OPTIONAL CONFIGURATION STEPS

You may wish to set some environment variables. The LINUX version of Free Pascal recognizes the following variables :

PPC_EXEC_PATH contains the directory where 'as' and 'ld' are. (default /usr/bin) PPC_GCCLIB_PATH contains the directory where libgcc.a is (no default) PPC_CONFIG_PATH specifies an alternate path to find ppc386.cfg (default /etc) PPC_ERROR_FILE specifies the path and name of the error-definition file. (default

/usr/lib/ppc/errorE.msg) These locations are, however, set in the sample configuration file which is built at the end of the installation process, except for the PPC_CONFIG_PATH variable, which you must set if you didn't install things in the default places.

FINALLY

Also distributed in Free Pascal is a README file. It contains the latest instructions for installing Free Pascal, and should always be read first.

TESTING THE COMPILER

After the installation is completed and the environment variables are set as described above, your first program can be compiled. Included in the Free Pascal distribution are some demonstration programs, showing what the compiler can do. You can test if the compiler functions correctly by trying to compile these programs. The compiler is called

PPC386.EXE under DOS, and ppc386 under LINUX

To compile a program (e.g demo\hello.pp) simply type : ppc386 helloat the command prompt. If you got no error messages, the compiler has generated an executable called hello (no extension) under LINUX, and a file hello.exe under DOS. To execute the program, simply type : helloIf all went well, you should see the following friendly greeting: Hello worldIn the DOS case, this friendly greeting may be preceded by some ugly message from the GO32 extender program. This unfriendly behavior can be switched off by setting the GO32 environment variable.

Free Pascal Manual Page 7

Page 8: Free Pascal Manual

COMPILER USAGE  Here we describe the essentials to compile a program and a unit. We also describe how to make a stand-alone executable of the compiled program under DOS. For more advanced uses of the compiler, see the section on configuring the compiler, and the Programmer's guideThe examples in this section suppose that you have a ppc386.cfg which is set up correctly, and which contains at least the path setting for the RTL units. In principle this file is generated by the installation program. You may have to check that it is in the correct place (see section 5.2 for more information on this).

Compiling a program Compiling a unit Creating an executable for GO32V1 and PMODE/DJ targets Reducing the size of your program

COMPILING A PROGRAM

Compiling a program is very simple. Assuming that you have a program source in the file prog.pp, you can compile this with the following command: ppc386 [options] prog.ppThe square brackets [] indicate that what is between them is optional. If your program file has the .pp or .pas extension, you can omit this on the command line, e.g. in the previous example you could have typed: ppc386 [options] progIf all went well, the compiler will produce an executable, or, for version 1 of the DOS extender, a file which can be converted to an executable. Under LINUX and version 2 of the DOS extender, the file you obtained is the executable. You can execute it straight away, you don't need to do anything else. Under DOS, additional processing is required. See the section on creating an executable. You will notice that there is also anothe file in your directory, with extensions .o. This contains, the object file for your program. If you compiled a program, you can delete the object file (.o), but not if you compiled a unit. Then the object file contains the code of the unit, and will be linked in any program that uses the unit you compiled, so you shouldn't remove it.

COMPILING A UNIT

Compiling a unit is not essentially different from compiling a program. The difference is mainly that the linker isn't called in this case. To compile a unit in the file foo.pp, just type : ppc386 fooRecall the remark about file extensions in the previous section. When all went well, you will be left with 2 (two) unit files:

1. foo.ppu This is the file describing the unit you just compiled.2. foo.o This file contains the actual code of the unit. This file will eventually end up in the

executables. Both files are needed if you plan to use the unit for some programs. So don't delete them. If you want to distribute the unit, you must provide both the .ppu and .o file. One is useless without the other.

CREATING AN EXECUTABLE FOR GO32V1 AND PMODE/DJ TARGETS

This section applies only to DOS users. LINUX users can skip this section (unless they're cross-compiling)

Page 8 Free Pascal Manual

Page 9: Free Pascal Manual

GO32V1

When compiling under DOS, GO32V2 is the default target. However, if you use go32V1 (using the -TDOS switch), the compilation process leaves you with a file which you cannot execute right away. There are 2 things you can do when compiling has finished. The first thing is to use the DOS extender from D.J. Delorie to execute your program : go32 progThis is fine for testing, but if you want to use a program regularly, it would be easier if you could just type the program name, i.e. progThis can be accomplished by making a DOS executable of your compiled program. There two ways to create a DOS executable (under DOS only):

1. if the GO32.EXE is already installed on the computers where the program should run, you must only copy a program called STUB.EXE at the begin of the AOUT file. This is accomplished with the AOUT2EXE.EXE program. which comes with the compiler: AOUT2EXE PROGand you get a DOS executable which loads the GO32.EXE automatically. the GO32.EXE executable must be in current directory or be in a directory in the PATH variable.

2. The second way to create a DOS executable is to put GO32.EXE at the beginning of the AOUT file. To do this, at the command prompt, type : COPY /B GO32.EXE+PROG PROG.EXE(assuming Free Pascal created a file called PROG, of course.) This becomes then a stand-alone executable for DOS, which doesn't need the GO32.EXE on the machine where it should run.

PMODE/DJ

You can also use the PMODE/DJ extender to run your Free Pascal applications. To make an executable which works with the PMODE extender, you can simply create an GO32V2 executable (the default), and then convert it to a PMODE executable with the following two extra commands:

1. First, strip the GO32V2 header of the executable: EXE2COFF PROG.EXE(we suppose that PROG.EXE is the program generated by the compilation process.

2. Secondly, add the PMODE stub: COPY /B PMODSTUB.EXE+PROG PROG.EXEIf the PMODSTUB.EXE file isn't in your local directory, you need to supply the whole path to it.

That's it. No additional steps are needed to create a PMODE extender executable. Be aware, though, that the PMODE extender doesn't support virtual memory, so if you're short on memory, you may run unto trouble. Also, officially there is not support for the PMODE/DJ extender. It just happens that the compiler and some of the programs it generates, run under this extender too.

REDUCING THE SIZE OF YOUR PROGRAM

When you created your program, it is possible to reduce its size. This is possible, because the compiler leaves a lot of information in the program which, strictly speaking, isn't required for the execution of it. The surplus of information can be removed with a small program called strip. It comes with the GO32 development environment under DOS, and is standard on LINUX machines where you can do development. The usage is simple. Just type strip progOn the command line, and the strip program will remove all unnecessary information from your program. This can lead to size reductions of up to 30 %. You can use the -Xs switch to let the compiler do this stripping automatically.

Free Pascal Manual Page 9

Page 10: Free Pascal Manual

COMPILING PROBLEMS

General problems Problems you may encounter under DOS

GENERAL PROBLEMS

IO-error -2 at ... : Under LINUX you can get this message at compiler startup. It means typically that the compiler doesn't find the error definitions file. You can correct this mistake with the -Fr option under LINUX. (See 5.1)

Error : File not found : xxx This typically happens when your unit path isn't set correctly. Remember that the compiler looks for units only in the current directory, and in the directory where the compiler itself is. If you want it to look somewhere else too, you must explicitly tell it to do so using the -Up option (See 5.1).

PROBLEMS YOU MAY ENCOUNTER UNDER DOS

No space in environment.An error message like this can occur, if you call SET_PP.BAT in the AUTOEXEC.BAT.To solve this problem, you must extend your environment memory. To do this, search a line in the CONFIG.SYS like SHELL=C:\DOS\COMMAND.COMand change it to the following: SHELL=C:\DOS\COMMAND.COM /E:1024You may just need to specify a higher value, if this parameter is already set.

Coprocessor missingIf the compiler writes a message that there is no coprocessor, install the coprocessor emulation.

Not enough DPMI memoryIf you want to use the compiler with DPMI you must have at least 7-8 MB free DPMI memory.

Page 10 Free Pascal Manual

Page 11: Free Pascal Manual

COMPILER CONFIGURATION

  The output of the compiler can be controlled in many ways. This can be done essentially in two distinct ways:

Using command-line options. Using the configuration file: ppc386.cfg.

The compiler first reads the configuration file. Only then the command line options are checked. This creates the possibility to set some basic options in the configuration file, and at the same time you can still set some specific options when compiling some unit or program. First we list the command line options, and then we explain how to specify the command line options in the configuration file. When reading this, keep in mind that the options are case sensitive. While this is customary for LINUX, it isn't under DOS.

Using the command-line options Using the configuration file

USING THE COMMAND-LINE OPTIONS

The available options are listed by category:

General options

-h if you specify this option, the compiler outputs a list of all options, and exits after that.  

-? idem as -h.

-i This option tells the compiler to print the copyright information.  

-l This option tells the compiler to print the Free Pascal logo on standard output. It also gives you the Free Pascal version number.  

-Lx Set the language the compiler uses for its messages.   x can be one of the following: D : Use German.E : Use English.

-n Tells the compiler not to read the configuration file.  

Options for getting feedback

-vxxx Be verbose. xxx is a combination of the following :   e : Tells the compiler to show only errors. This option is on by default.i : Tells the compiler to show some general information.w : Tells the compiler to issue warnings.n : Tells the compiler to issue notes.h : Tells the compiler to issue hints.l : Tells the compiler to show the line numbers as it processes a file. Numbers are shown per 100.u : Tells the compiler to print the names of the files it opens.t : Tells the compiler to print the names of the files it tries to open.

Free Pascal Manual Page 11

Page 12: Free Pascal Manual

p : Tells the compiler to print the names of procedures and functions as it is processing them.c : Tells the compiler to warn you when it processes a conditional.m : Tells the compiler to write which macros are defined.d : Tells the compiler to write other debugging info.a : Tells the compiler to write all possible info. (this is the same as spcifying all options)0 : Tells the compiler to write no messages. This is useful when you want to override the default setting in the configuration file.

Options concerning files and directories

-exxx (LINUX only) xxx specifies the directory where the compiler can find the executables as (the assembler) and ld (the compiler).  

-Fexxx This option tells the compiler to write errors, etc. to the file in xxx.  

-Fgxxx (LINUX only) xxx specifies the path where the compiler can find the gnu C library.  

-Fixxx adds xxx to the path where the compiler searches for its include files.  

-Flxxx Adds xxx to the library searching path, and is passed to the linker.  

-Frxxx (LINUX only) xxx specifies the path where the compiler can find the error-definitions file.  

-Fuxxx Idem as -Up.  

-P uses pipes instead of files when assembling. This may speed up the compiler on OS/2 and LINUX. Only with assemblers (such as gnu as) that support piping..

-Upxxx   Tells the compiler to add xxx to the path where to find units. By default, the compiler only searches for units in the current directory and the directory where the compiler itself resides. This option tells the compiler also to look in the directory xxx.

Options controlling the kind of output.

for more information on these options, see also Programmer's guide\ -a

  Tells the compiler not to delete the assembler file. This also counts for the (possibly) generated batch script.

-Axxx  specifies what kind of assembler should be generated . Here xxx is one of the following : att : AT&T assembler.o : A unix .o (object) file.obj : A OMF file for using the NASM assembler.nasm : a coff file using the NASM assembler.masm : An assembler file for the Microsoft/Borland/Watcom assembler.

-CD Force dynamic linking.

-Chxxx   Reserves xxx bytes heap.

-Ci   Generate Input/output checking code.

Page 12 Free Pascal Manual

Page 13: Free Pascal Manual

-Cn   Omit the linking stage.

-Co   Generate Integer overflow checking code.

-Cr   Generate Range checking code.

-Csxxx   Set stack size to xxx. (OS/2 only).

CS   Statically link your program/unit.

-Ct   generate stack checking code.

-dxxx   Define the symbol name xxx. This can be used to conditionally compile parts of your code. -E   Same as -Cn.

-g   Generate debugging information for debugging with gdb.

-gp   Generate profiler code for gprof.

-On   optimize the compiler's output; n can have one of the following values :

a simple optimizations

g optimize for size

G optimize for time

x optimize maximum

z uncertain optimizations

2 optimize for Pentium II (tm)

3 optimize for i386

4 optimize for i486

5 optimize for Pentium (tm)

6 optimizations for PentiumPro (tm)

The exact effect of these effects can be found in the appendices of the Programmer's guide.-oxxx

Tells the compiler to use xxx as the name of the output file (executable). Only with programs. -pg

Tells the compiler to issue code for profiling support. -s

  Tells the compiler not to call the assembler and linker. Instead, the compiler writes a script, PPAS.BAT under DOS, or ppas.sh under LINUX, which can then be executed to produce an executable.

-Txxx  Specifies the target operating system. xxx can be one of the following: DOS : DOS and the DJ DELORIE extender.OS2 : OS/2 (2.x) (this is still under development).LINUX : LINUX.

Free Pascal Manual Page 13

Page 14: Free Pascal Manual

WIN32 : Windows 32 bit (this is still under development).GO32V2 : DOS and version 2 of the DJ DELORIE extender.

-Uld   make dynamic library from unit.

-Uls   make static library from unit.

-uxxx   Undefine symbol xxx.

-Xx   executable options. This tells the compiler what kind of LINUX executable should be generated. the parameter x can be one of the following: c : (LINUX only) Link with the C library. You should only use this when you start to port Free Pascal to another operating system.s : (DOS only) Strip the symbols from the executable.

Options concerning the sources (language options)

for more information on these options, see also Programmer's guide\ -Rxxx

  Specifies what assembler you use in your asm assembler code blocks. Here xxx is one of the following:

att asm blocks contain AT&T assembler.

intel asm blocks contain Intel assembler.

direct asm blocks should be copied as-is in the assembler file.

-S2   Switch on Delphi 2 extensions.

-Sc   Support C-style operators, i.e. *=, +=, /= and -=.

-Se   The compiler stops after the first error. Normally, the compiler tries to continue compiling after an error, until 50 errors are reached, or a fatal error is reachd, and then it stops. With this switch, the compiler will stop after the first error.

-Sg   Support the label and goto commands.

-Si   Support C++ style INLINE.

-Sm   Support C-style macros.

-So   Try to be Borland TP compatible (no function overloading etc.).

-Ss   The name of constructors must be init, and the name of destructors should be done.

-St   Allow the static keyword in objects.

-Un   Do not check the unit name. (Normally, the unit name is the same as the filename. This option allows both to be different.)

-Us   Compile a system unit. This option causes the compiler to define only some very basic types.

Page 14 Free Pascal Manual

Page 15: Free Pascal Manual

USING THE CONFIGURATION FILE

  Using the configuration file ppc386.cfg is an alternative to command line options. When a configuration file is found, it is read, and the lines in it are treated like you typed them on the command line. They are treated before the options that you type on the command line. You can specify comments in the configuration file with the # sign. Everything from the # on will be ignored. The compiler looks for the ppc386.cfg file in the following places :

1. The current directory.2. Under DOS, the directory where the compiler is. Under LINUX, the compiler looks in the

/etc directory3. if specified, the directory in the PPC_CONFIG_PATH environment variable.

When the compiler has finished reading the configuration file, it continues to treat the command line options. One of the command-line options allows you to specify a second configuration file: Specifying @foo on the command line will open file foo, and read further options from there. When the compiler has finished reading this file, it continues to process the command line. An important feature in the configuration file is that you can specify sections. They behave much like conditional defines. Suppose the following configuration file (named myconf) -a#section first-Up/some_path#section second-Up/other_path.When you invoke the compiler as follows: ppc386 -dfirst @myconf foo.ppthen the compiler will read the part of the configuration file coming before the line containing #section second. As a result the unit search path will be set to /some_path. If, on the other hand, you invoke the compiler as ppc386 -dsecond @myconf foo.ppThen the configuration file will be read as if the part between #section first and #section second didn't exist, resulting in a unit search path of /other_path. If you put a #section common on a line, everything that follows this keyword will be read, whatever the defined constants. In short, the #define keywords act as conditionals.

Free Pascal Manual Page 15

Page 16: Free Pascal Manual

PORTING TURBO PASCAL CODE

Free Pascal was designed to resemble Turbo Pascal as closely as possible. There are, of course, restrictions. Some of these are due to the fact that Free Pascal is a 32-bit compiler. Other restrictions result from the fact that Free Pascal works on more than one operating system. In general we can say that if you keep your program code close to ANSI Pascal, you will have no problems porting from Turbo Pascal, or even Delphi, to Free Pascal. To a large extent, the constructs defined by Turbo Pascal are supported. In the following sections we will list the Turbo Pascal constructs which are not supported in Free Pascal, and we will list in what ways Free Pascal extends the Turbo Pascal language.

Things that will not work Things which are extra Turbo Pascal compatibility mode

THINGS THAT WILL NOT WORK

Here we give a list of things which are defined/allowed in Turbo Pascal, but which are not supported by Free Pascal. Where possible, we indicate the reason.

1. Parameter lists of previously defined functions and procedures must match exactly. The reason for this is the function overloading mechanism of Free Pascal. (however, See 5.1)

2. (* ... *) as comment delimiters are not allowed in versions older than 0.9.1. This can easily be remedied with a grown-up editor.

3. The MEM, MEMW, MEML and PORT variables for memory and port access are not available. This is due to the operating system. Under DOS, the extender unit (GO32.PPU provides functions to remedy this.

4. PROTECTED, PUBLIC, TRY, THROW, EXCEPTION are reserved words. This means you cannot create procedures or variables with the same name. While they are not reserved words in Turbo Pascal, they are in Delphi.

5. The reserved words FAR, NEAR are ignored. This is because Free Pascal is a 32 bit compiler, so they're obsolete.

6. INTERRUPT only will work on a DOS machine.7. Boolean expressions are only evaluated until their result is completely determined. The rest

of the expression will be ignored.8. At the moment of writing, the assembler syntax used in Free Pascal is AT&T assembler

syntax. This is mainly because Free Pascal uses gnu as.9. Turbo Vision is not available.10. The 'overlay' unit is not available. It also isn't necessary, since Free Pascal is a 32 bit

compiler, so program size shouldn't be a point.11. There are more reserved words. (see appendix B for a list of all reserved words.)12. The command-line parameters of the compiler are different.13. The compiler switches behave different.14. Units are not binary compatible. 15.

THINGS WHICH ARE EXTRA

Here we give a list of things which are possible in Free Pascal, but which didn't exist in Turbo Pascal or Delphi.

1. There are more reserved words. (see appendix B for a list of all reserved words.)2. Functions can also return complex types, such as records and arrays.3. You can handle function results in the function itself, as a variable. Example

function a : longint;

Page 16 Free Pascal Manual

Page 17: Free Pascal Manual

begin a:=12; while a>4 do begin {...} end;end;The example above would work with TP, but the compiler would assume that the a>4 is a recursive call. To do a recursive call in this you must append () behind the function name: function a : longint;

begin a:=12; { this is the recursive call } if a()>4 then begin {...} end;end;

4. There is partial support of Delphi constructs. (see the Programmer's guide for more information on this).

5. The exit call accepts a return value for functions. function a : longint;

begin a:=12; if a>4 then begin exit(a*67); {function result upon exit is a*67 } end;end;

6. Free Pascal supports function overloading. That is, you can define many functions with the same name, but with different arguments. For example: procedure DoSomething (a : longint);begin{...}end;

procedure DoSomething (a : real);begin{...}end;You can then call procedure DoSomething with an argument of type Longint or Real.This feature has the consequence that a previously declared function must always be defined with the header completely the same: procedure x (v : longint); forward;

{...}

procedure x;{ This will overload the previously declared x}begin{...}end;This construction will generate a compiler error, because the compiler didn't find a definition of procedure x (v : longint);. Instead you should define your procedure x as:

Free Pascal Manual Page 17

Page 18: Free Pascal Manual

procedure x (v : longint);{ This correctly defines the previously declared x}begin{...}end;

TURBO PASCAL COMPATIBILITY MODE

When you compile a program with the -So switch, the compiler will attempt to mimic the Turbo Pascal compiler in the following ways:

Assigning a procedural variable doesn't require a @ operator. One of the differences between Turbo Pascal and Free Pascal is that the latter requires you to specify an address operator when assigning a value to a procedural variable. In Turbo Pascal compatibility mode, this is not required.

Procedure overloading is disabled. Forward defined procedures don't need the full parameter list when they are defined. Due to

the procedure overloading feature of Free Pascal, you must always specify the parameter list of a function when you define it, even when it was declared earlier with Forward. In Turbo Pascal compatibility mode, there is no function overloading, hence you can omit the parameter list: Procedure a (L : Longint); Forward;

...

Procedure a ; { No need to repeat the (L : Longint) }

begin ...end;

recursive function calls are handled dfferently. Consider the following example : Function expr : Longint;

begin ... Expr:=L: Writeln (Expr); ...end;In Turbo Pascal compatibility mode, the function will be called recursively when the writeln statement is processed. In Free Pascal, the function result will be printed. In order to call the function recusively under Free Pascal, you need to implement it as follows : Function expr : Longint;

begin ... Expr:=L: Writeln (Expr()); ...end;

Any text after the final End. statement is ignored. Normally, this text is processed too. You cannot assign procedural variables to void pointers. The @ operator is typed when applied on procedures. You cannot nest comments.

Page 18 Free Pascal Manual

Page 19: Free Pascal Manual

UTILITIES AND UNITS THAT COME WITH FREE PASCAL

  Besides the compiler and the Run-Time Library, Free Pascal comes with some utility programs and units. Here we list these programs and units.

Supplied programs Supplied units

SUPPLIED PROGRAMS

dumppu is a program which shows the contents of a Free Pascal unit. It comes in source form, and must be compiled before you can use it. Once compiled, you can just issue the following command dumppu foo.pputo display the contents of the foo.ppu unit.

Also distributed with Free Pascal comes a series of demonstration programs. These programs have no other purpose than demonstrating the capabilities of Free Pascal. They are located in the demo directory of the sources.

All example programs of the documentation are available. Check out the directories that end on ex in the documentation sources. There you will find all example sources.

ppumove is a program to make shared or static libraries from units. It should be distributed in binary form along with the compiler.

SUPPLIED UNITS

Here we list the units that come with the Free Pascal distribution. Since there is a difference in the supplied units per operating system, we list them separately per system. They are documented in the Unit reference.

Under DOS

strings This unit provides basic string handling routines for the pchar type, comparable to similar routines in standard C libraries.

objects This unit provides basic routines for handling objects.

dos This unit provides basic routines for accessing the operating system DOS. It provides almost the same functionality as the Turbo Pascal unit.

printer This unit provides all you need for rudimentary access to the printer.

getopts This unit gives you the gnu getopts command-line arguments handling mechanism. It also supports long options.

crt This unit provides basic screen handling routines. It provides the same functionality as the Turbo Pascal CRT unit.

graph This unit provides basic graphics handling, with routines to draw lines on the screen, display texts etc. It provides the same functions as the Turbo Pascal unit.

go32

Free Pascal Manual Page 19

Page 20: Free Pascal Manual

This unit provides access to possibilities of the GO32 DOS extender. emu387

This unit provides support for the coprocessor emulator. mmx

This unit provides support for mmx extensions in your code.

Under Linux

strings This unit provides basic string handling routines for the PChar type, comparable to similar routines in standard C libraries.

objects This unit provides basic routines for handling objects.

crt This unit provides basic screen handling routines. It provides the same functionality Turbo Pascal CRT unit. It works on any terminal which supports the vt100 escape sequences.

dos This unit provides an emulation of the same unit under DOS. It is intended primarily for easy porting of Pascal programs from DOS to LINUX. For good performance, however, it is recommended to use the linux unit.

linux This unit provides access to the LINUX operating system. It provides most file and I/O handling routines that you may need. It implements most of the standard C library constructs that you will find on a Unix system. If you do a lot of disk/file operations, the use of this unit is recommended over the one you use under Dos.

printer This unit provides an interface to the standard Unix printing mechanism.

getopts This unit gives you the gnu getopts command-line arguments handling mechanism. It also supports long options.

mmx This unit provides support for mmx extensions in your code.

sockets This unit gives you access to sockets and TCP/IP programming.

Page 20 Free Pascal Manual

Page 21: Free Pascal Manual

DEBUGGING YOUR PROGRAMS

Free Pascal supports debug information for the gnu debugger gdb. This chapter describes shortly how to use this feature. It doesn't attempt to describe completely the gnu debugger, however. For more information on the workings of the gnu debugger, see the gdb users' guide. Free Pascal also suports gprof, the gnu profiler, see section 8.4 for more information on profiling.

Compiling your program with debugger support Using gdb to debug your program Caveats when debugging with gdb Support for gprof , the gnu profiler

COMPILING YOUR PROGRAM WITH DEBUGGER SUPPORT

First of all, you must be sure that the compiler is compiled with debugging support. Unfortunately, there is no way to check this at run time, except by trying to compile a program with debugging support. To compile a program with debugging support, just specify the -g option on the command-line, as follows: ppc386 -g hello.ppThis will generate debugging information in the executable from your program. You will notice that the size of the executable increases substantially because of this. Note that the above will only generate debug information for the code that has been generated when compiling hello.pp. This means that if you used some units (the system unit, for instance) which were not compiled with debugging support, no debugging support will be available for the code in these units. There are 2 solutions for this problem.

1. Recompile all units manually with the -g option.2. Specify the 'build' option (-B) when compiling with debugging support. This will recompile

all units, and insert debugging information in each of the units. The second option may have undesirable side effects. It may be that some units aren't found, or compile incorrectly due to missing conditionals, etc.. If all went well, the executable now contains the necessary information with which you can debug it using gnu gdb.

USING GDB TO DEBUG YOUR PROGRAM

To use gdb to debug your program, you can start the debugger, and give it as an option the name of your program: gdb helloThis starts the debugger, and the debugger immediately loads your program into memory, but it does not run the program yet. Instead, you are presented with the following (more or less) message, followed by the gdb prompt '(gdb)': GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions.There is absolutely no warranty for GDB; type "show warranty" for details.GDB 4.15.1 (i486-slackware-linux),Copyright 1995 Free Software Foundation, Inc...(gdb)To start the program you can use the run command. You can optionally specify command-line parameters, which will then be fed to your program, for example: (gdb) run -option -anotheroption needed_argument

Free Pascal Manual Page 21

Page 22: Free Pascal Manual

If your program runs without problems, gdb will inform you of this, and return the exit code of your program. If the exit code was zero, then the message 'Program exited normally'. If something went wrong (a segmentation fault or so), gdb will stop the execution of your program, and inform you of this with an appropriate message. You can then use the other gdb commands to see what happened. Alternatively, you can instruct gdb to stop at a certain point in your program, with the break command. Here is a short list of gdb commands, which you are likely to need when debugging your program: quit

Exits the debugger. kill

Stops a running program. help

Gives help on all gdb commands. file

Loads a new program into the debugger. directory

Add a new directory to the search path for source files.Remark: My copy of gdb needs '.' to be added explicitly to the search path, otherwise it doesn't find the sources.

list Lists the program sources per 10 lines. As an option you can specify a line number or function name.

break Sets a breakpoint at a specified line or function

awatch Sets a watch-point for an expression. A watch-point stops execution of your program whenever the value of an expression is either read or written.

for more information, see the gdb users' guide, or use the 'help' function in gdb. The appendix F contains a sample init file for gdb, which produces good results when debugging Free Pascal programs.

CAVEATS WHEN DEBUGGING WITH GDB

There are some peculiarities of Free Pascal which you should be aware of when using gdb. We list the main ones here:

1. Free Pascal generates information for GDB in uppercare letters. This is a consequence of the fact that pascal is a case insensitive language. So, when referring to a variable or function, you need to make it's name all uppercase. As an example, of you want to watch the value of a loop variable count, you should type watch COUNTOr if you want stop when a certain function (e.g MyFunction) is called, type break MYFUNCTION

2. Line numbers may be off by a little. This is a bug in Free Pascal and will be fixed as soon as possible.

3. gdb does not know sets.4. gdb doesn't know strings. Strings are represented in gdb as records with a length field and

an array of char contaning the string. You can also use the following user function to print strings: define pstset $pos=&$arg0set $strlen = {byte}$posprint {char}&$arg0.st@($strlen+1)end

Page 22 Free Pascal Manual

Page 23: Free Pascal Manual

document pst Print out a Pascal stringendIf you insert it in your gdb.ini file, you can look at a string with this function. There is a sample gdb.ini in appendix F.

5. Objects are difficult to handle, mainly because gdb is oriented towards C and C++. The workaround implemented in Free Pascal is that object methods are represented as functions, with an extra parameter this (all lowercase !) The name of this function is a concatenation of the object type and the function name, separated by two underscore characters. For example, the method TPoint.Draw would be converted to TPOINT__DRAW, and could be stopped at with break TPOINT__DRAW

6. Global overloaded functions confuse gdb because they have the same name. Thus you cannot set a breakpoint at an overloaded function, unless you know it's line number, in which case you can set a breakpoint at the starting linenumber of the function.

7.

SUPPORT FOR GPROF, THE GNU PROFILER

  You can compile your programs with profiling support. for this, you just have to use the compiler switch -pg. The compiler wil insert the necessary stuff for profiling. When you have done this, you can run your program uder the gnu profiler, gprof, as follows : gprog yourexeWhere yourexe is the name of your executable. You may want to capture the outpus of the profiler in a file, since it can be quite a lot, as follows: gprog yourexe >gprof.outFor more information on the gnu profiler gprof, see its manual.

Free Pascal Manual Page 23

Page 24: Free Pascal Manual

CGI PROGRAMMING IN FREE PASCAL

  In these days of heavy WWW traffic on the Internet, CGI scripts have become an important topic in computer programming. While CGI programming can be done with almost any tool you wish, most languages aren't designed for it. Perl may be a notable exception, but perl is an interpreted language, the executable is quite big, and hence puts a big load on the server machine. Because of its simple, almost intuitive, string handling and its easy syntax, Pascal is very well suited for CGI programming. Pascal allows you to quickly produce some results, while giving you all the tools you need for more complex programming. The basic RTL routines in principle are enough to get the job done, but you can create, with relatively little effort, some units which can be used as a base for more complex CGI programming. That's why, in this chapter, we will discuss the basics of CGI in Free Pascal. In the subsequent, we will assume that the server for which the programs are created, are based upon the NCSA httpd WWW server, as the examples will be based upon the NCSA method of CGI programming. The two example programs in this chapter have been tested on the command line and worked, under the condition that no spaces were present in the name and value pairs provided to them.

Getting your data Producing output I'm under Windows, what now ?

GETTING YOUR DATA

Your CGI program must react on data the user has filled in on the form which your web-server gave him. The Web server takes the response on the form, and feeds it to the CGI script. There are essentially two ways of feeding the data to the CGI script. We will discuss both.

Data coming through standard input.

The first method of getting your data is through standard input. This method is invoked when the form uses a form submission method of POST. The web browser sets three environment variables REQUEST_METHOD, CONTENT_TYPE and CONTENT_LENGTH. It feeds then the results of the different fields through standard input to the CGI script. All the Pascal program has to do is :

Check the value of the REQUEST_METHOD environment variable. The getenv function will retrieve this value this for you.

Check the value of the CONTENT_TYPE environment variable. Read CONTENT_LENGTH characters from standard input. read (c) with c of type char

will take care of that. if you know that the request method will always be POST, and the CONTENT_TYPE will be correct, then you can skip the first two steps. The third step can be done easier: read characters until you reach the end-of-file marker of standard input. The following example shows how this can be achieved: program cgi_post;

uses dos;

const max_data = 1000;

type datarec = record name,value : string; end;

Page 24 Free Pascal Manual

Page 25: Free Pascal Manual

var data : array[1..max_data] of datarec; i,nrdata : longint; c : char; literal,aname : boolean;

beginwriteln ('Content-type: text/html');writeln;if getenv('REQUEST_METHOD')<>'POST' then begin writeln ('This script should be referenced with a METHOD of POST'); write ('If you don''t understand this, see this '); write ('< A HREF="http://www.ncsa.uiuc.edu/SDG/Softare/Mosaic'); writeln ('/Docs/fill-out-forms/overview.htm">forms overview</A>.'); halt(1); end;if getenv('CONTENT_TYPE')<>'application/x-www-form-urlencoded' then begin writeln ('This script can only be used to decode form results'); halt(1) end;nrdata:=1;aname:=true;while not eof(input) do begin literal:=false; read(c); if c='\' then begin literal:=true; read(c); end; if literal or ((c<>'=') and (c<>'&')) then with data[nrdata] do if aname then name:=name+c else value:=value+c else begin if c='&' then begin inc (nrdata); aname:=true; end else aname:=false; end end;writeln ('<H1>Form Results :</H1>');writeln ('You submitted the following name/value pairs :');writeln ('<UL>');for i:=1 to nrdata do writeln ('<LI> ',data[i].name,' = ',data[i].value);writeln ('</UL>');end.While this program isn't shorter than the C program provided as an example at NCSA, it doesn't need

Free Pascal Manual Page 25

Page 26: Free Pascal Manual

any other units. everythig is done using standard Pascal procedures. Note that this program has a limitation: the length of names and values is limited to 255 characters. This is due to the fact that strings in Pascal have a maximal length of 255. It is of course easy to redefine the datarec record in such a way that longer values are allowed. In case you have to read the contents of a TEXTAREA form element, this may be needed.

Data passed through an environment variable

If your form uses the GET method of passing it's data, the CGI script needs to read the QUERY_STRING environment variable to get it's data. Since this variable can, and probably will, be more than 255 characters long, you will not be able to use normal string methods, present in pascal. Free Pascal implements the pchar type, which is a pointer to a null-terminated array of characters. And, fortunately, Free Pascal has a strings unit, which eases the use of the pchar type. The following example illustrates what to do in case of a method of GET program cgi_get;

uses strings,linux;

const max_data = 1000;

type datarec = record name,value : string; end;

var data : array[1..max_data] of datarec; i,nrdata : longint; p : PChar; literal,aname : boolean;

beginWriteln ('Content-type: text/html');Writeln;if StrComp(GetEnv('REQUEST_METHOD'),'POST')<>0 then begin Writeln ('This script should be referenced with a METHOD of GET'); write ('If you don''t understand this, see this '); write ('< A HREF="http://www.ncsa.uiuc.edu/SDG/Softare/Mosaic'); Writeln ('/Docs/fill-out-forms/overview.htm">forms overview</A>.'); halt(1); end;p:=GetEnv('QUERY_STRING');nrdata:=1;aname:=true;while p^<>#0 do begin literal:=false; if p^='\' then begin literal:=true; inc(longint(p)); end; if ((p^<>'=') and (p^<>'&')) or literal then with data[nrdata] do if aname then name:=name+p^ else value:=value+p^

Page 26 Free Pascal Manual

Page 27: Free Pascal Manual

else begin if p^='&' then begin inc (nrdata); aname:=true; end else aname:=false; end; inc(longint(p)); end;Writeln ('<H1>Form Results :</H1>');Writeln ('You submitted the following name/value pairs :');Writeln ('<UL>');for i:=1 to nrdata do writeln ('<LI> ',data[i].name,' = ',data[i].value);Writeln ('</UL>');end.Although it may not be written in the most elegant way, this program does the same thing as the previous one. It also suffers from the same drawback, namely the limited length of the value field of the datarec. This drawback can be remedied by redefining datarec as follows: type datarec = record; name,value : pchar; end;and assigning at run time enough space to keep the contents of the value field. This can be done with a getmem (data[nrdata].value,needed_number_of_bytes);call. After that you can do a strlcopy (data[nrdata].value,p,needed_number_of_bytes);to copy the data into place. You may have noticed the following unorthodox call : inc(longint(p));Free Pascal doesn't give you pointer arithmetic as in C. However, longints and pointers have the same length (namely 4 bytes). Doing a type-cast to a longint allows you to do arithmetic on the pointer. Note however, that this is a non-portable call. This may work on the I386 processor, but not on a ALPHA processor (where a pointer is 8 bytes long). This will be remedied in future releases of Free Pascal.

PRODUCING OUTPUT

The previous section concentrated mostly on getting input from the web server. To send the reply to the server, you don't need to do anything special.You just print your data on standard output, and the Web-server will intercept this, and send your output to the WWW-client waiting for it. You can print anything you want, the only thing you must take care of is that you supply a Contents-type line, followed by an empty line, as follows: Writeln ('Content-type: text/html');Writeln;{ ...start output of the form... }And that's all there is to it !

I'M UNDER WINDOWS, WHAT NOW ?

Under Windows the system of writing CGI scripts is totally different. If you use Free Pascal under

Free Pascal Manual Page 27

Page 28: Free Pascal Manual

Windows then you also should be able to do CGI programming, but the above instructions will not work. If some kind soul is willing to write a section on CGI programming under Windows, I'd be willing to include it here.

ALPHABETICAL LISTING OF COMMAND-LINE OPTIONS

The following is alphabetical listing of all command-line options, as generated by the compiler: ppc386 [options] <inputfile> [options]+ switch option on, - off -a the compiler doesn't delete the generated assembler file -B+ build -C code generation options -Ca not implemented -Ce not implemented -CD Dynamic linking -Ch<n> <n> bytes heap (between 1023 and 67107840) -Ci IO-checking -Cn omit linking stage -Co check overflow of integer operations -Cr range checking -Ct stack checking -CS static linking -d<x> defines the symbol <x> -e<x> set path to executables -E same as -Cn -g generate debugger information -gp generate also profile code for gprof -F set file names and paths -Fe<x> redirect error output to <x> -Fg<x> <x> search path for the GNU C lib -Fr<x> <x> search path for the error message file -Fi<x> adds <x> to include path -Fl<x> adds <x> to library path -Fu<x> adds <x> to unit path -k<x> Pass <x> to the linker -L set language -LD german -LE english -l write logo -i information -n don't read the default config file -o<x> change the name of the executable produced to <x> -pg generate profile code for gprof -P use pipes instead of creating temporary assembler files -S syntax options -S2 switch some Delphi 2 extension on -Sc supports operators like C (*=,+=,/= and -=) -Se compiler stops after the first error -Sg allows LABEL and GOTO -Si support C++ stlyed INLINE -Sm support macros like C (global) -So tries to be TP/BP 7.0 compatible -Ss constructor name must be init (destructor must be done) -St allows static keyword in objects

Page 28 Free Pascal Manual

Page 29: Free Pascal Manual

-s don't call assembler and linker (only with -a) -T<x> Target operating system -TDOS DOS extender by DJ Delorie -TOS2 OS/2 2.x -TLINUX Linux -TWin32 Windows 32 Bit -TGO32V2 version 2 of DJ Delorie DOS extender -u<x> undefines the symbol <x> -U unit options -Uls make static library from unit -Uld make dynamic library from unit -Un don't check the unit name -Up<x> same as -Fu<x> -Us compile a system unit -v<x> Be verbose. <x> is a combination of the following letters : e : Show errors (default) d : Show debug info w : Show warnings u : Show used files n : Show notes t : Show tried files h : Show hints m : Show defined macros i : Show general info p : Show compiled procedures l : Show linenumbers c : Show conditionals a : Show everything 0 : Show nothing (except errors) -X executable options -Xc link with the c library -Xs strip all symbols from executable

Processor specific options: -A output format -Aatt AT&T assembler -Ao coff file using GNU AS -Aobj OMF file using NASM -Anasm coff file using NASM -Amasm assembler for the Microsoft/Borland/Watcom assembler -R assembler reading style -Ratt read AT&T style assembler -Rintel read Intel style assembler -Rdirect copy assembler text directly to assembler file -O optimizations -Oa simple optimizations -Og optimize for size -OG optimize for time -Ox optimize maximum -Oz uncertain optimizes (see docs) -O2 optimize for Pentium II (tm) -O3 optimize for i386 -O4 optimize for i486 -O5 optimize for Pentium (tm) -O6 optimizations for PentiumPro (tm) -? shows this help -h shows this help without waiting

Free Pascal Manual Page 29

Page 30: Free Pascal Manual

COMPILER ERROR MESSAGES

  This appendix is meant to list all the compiler errors. the list of compiler errors is fairly complete, the assembler errors are less complete.

Compiler errors

COMPILER ERRORS

The following is a list of general compiler errors. unexpected end of file

this typically happens in on of the following cases : The source file ends befor then final end. statement. This happens mostly when the begin and end statements aren't balanced;An include file ends in the middle of a statement.A comment wasn't closed.

duplicate identifier: The identifier was already declared in the current scope.

syntax error: An error against the Turbo Pascal language was encountered. This happens typically when an illegal character is found in the sources file.

Parser - syntax error An error against the Turbo Pascal language was encountered. This happens typically when an illegal character is found in the sources file.

out of memory The compiler doesn't have enough memory to compile your program. There are several remedies for this: If you're using the build option of the compiler, try compiling the different units manually.If you're compiling a huge program, split it up in units, and compile these separately.If the previous two don't work, recompile the compiler with a bigger heap (you can use the -Ch option for this, See 5.1)

unknown identifier The identifier encountered hasn't been declared, or is used outside the scope where it's defined.

illegal character An illegal character was encountered in the input file.

source too long The compiler cannot cope with source files longer than (???)

procedure type INLINE not supported You tried to compile a program with C++ style inlining, and forgot to specify the -Si option (See 5.1). The compiler doesn't support C++ styled inlining by default.

procedure type NEAR ignored This is a warning. NEAR is a construct for 8 or 16 bit programs. Since the compile generates 32 bit programs, it ignores this directive.

procedure type FAR ignored This is a warning. FAR is a construct for 8 or 16 bit programs. Since the compile generates 32 bit programs, it ignores this directive.

INTERRUPT ignored Interrupt procedures aren't possible on operating systems, other than DOS, it isn't allowed to take over an interrupt at the user level. (versions older than 0.9.2 didn't have INTERRUPT support.

private methods shouldn't be VIRTUAL You declared a method in the private part of a object (class) as virtual. This is not allowed. Private methods cannot be overridden anyway.

Page 30 Free Pascal Manual

Page 31: Free Pascal Manual

constructor can't be private or protected Constructors must be in the 'public' part of an object (class) declaration.

destructor can't be private or protected Destructors must be in the 'public' part of an object (class) declaration.

identifier not found local class definitions are not allowed

Classes must be defined globally. anonym class definitions are not allowed type identifier expected

The identifier is not a type, or you forgot to supply a type identifier. identifier already as type identifier declared

You are trying to redefine a type. type identifier not defined

The compiler encountered an unknown type. type mismatch

This can happen in many cases: The variable you're assigning to is of a different type than the expression in the assignment.You are calling a function or procedure with parameters that are incompatible with the parameters in the function or procedure definition.

statement expected illegal integer constant

You made an exression which isn't an integer, and the compiler expects the result to be an integer. illegal expression expression too complicated - FPU stack overflow

Your expression is too long for the compiler. You should try dividing the construct over multiple assignments.

CONTINUE not allowed You're trying to use continue outside a loop construction.

BREAK not allowed You're trying to use break outside a loop construction.

illegal qualifier One of the following is appending : You're trying to access a field of a variable that is not a record.You're indexing a variable that is not an array.You're dereferencing a variable that is not a pointer.

illegal counter variable The type of a for loop must be ordinal.

ordinal value expected The expression must be of ordinal type (i.e. maximum a Longint)

high range limit < low range limit You are declaring a subrange, and the lower limit is higher than the high limit of the range.

illegal unit name The name of the unit doesn't match the file name.

unknown format of unit file The unit the compiler is trying to read is corrupted, or generated with a newer version of the compiler.

Reading PPU-File The unit the compiler is trying to read is corrupted, or generated with a newer version of the compiler.

Invalid PPU-File entry The unit the compiler is trying to read is corrupted, or generated with a newer version of the compiler.

circular unit use Two units are using each other in the interface part. This is only allowed in the implementation part.

Free Pascal Manual Page 31

Page 32: Free Pascal Manual

too many units Free Pascal has a limit of 1024 units in a program. You can change this behavior by changing the maxunits constant in the files.pas file of the compiler, and recompiling the compiler.

illegal char constant The compiler expects a character constant, but finds something else.

overloaded identifier isn't a function identifier The compiler encountered a symbol with the same name a s an overloaded function, but it isn't a function it can overload.

overloaded functions have the same parameter list You're declaring overloaded functions, but with the same parameter list. Overloaded function must have at least 1 different parameter in their declaration.

illegal parameter list You are calling a function with parameters that are of a different type than the declared parameters of the function.

can't determine which overloaded function to call You're calling overloaded functions with a parameter that doesn't correspond to any of the declared function parameter lists. e.g. when you have declared a function with parameters word and longint, and then you call it with a parameter which is of type integer.

forward declaration not solved: This can happen in two cases: This happens when you declare a function (in the interface part, or with a forward directive, but do not implement it.You reference a type which isn't declared in the current type block.

input file not found Free Pascal cannot find the program or unit source file, or the included file isn't found.

function header doesn't match the forward declaration You declared the function in the interface part, or with the forward directive, but define it with a different parameter list.

unknown field identifier The field doesn't exist in the record definition.

parameter list size exceeds 65535 bytes The I386 processor limits the parameter list to 65535 bytes (the RET instruction causes this)

function nesting > 31 You can nest function definitions only 31 times.

illegal compiler switch You included a compiler switch (i.e. {$... }) which the compiler doesn't know.

can't open include file You want to include (i.e {$i file}) which the compiler doesn't find. Check if the filename is correct.

record or class type expected The variable or expression isn't of the type record or class.

only values can be jumped over in enumeration types Free Pascal allows enumeration constructions as in C. Given the following declaration two declarations: type a = (A_A,A_B,A_E=:6,A_UAS:=200);type a = (A_A,A_B,A_E=:6,A_UAS:=4);The second declaration would produce an error. A_UAS needs to have a value higher than A_E, i.e. at least 7.

pointer type expected The variable or expression isn't of the type pointer.

unit is compiled for another operating system The unit was compiled with a different target than the target for which you're compiling now. (see the option -T See 5.1).

typed constants of classes are not allowed You cannot declare a constant of type class or object.

Page 32 Free Pascal Manual

Page 33: Free Pascal Manual

duplicate case label You are specifying the same label 2 times in a case statement.

range check error while evaluating constants The constants are out of their allowed range.

illegal type conversion When doing a type-cast, you must take care that the sizes of the variable and the destination type are the same.

class type expected The variable of expression isn't of the type class.

functions variables of overloaded functions are not allowed You are trying to assign an overloaded function to a procedural variable. This isn't allowed.

can't create assembler file The assembler output file cannot be opened. This can have many causes, but 'disk full' is a reasonable guess.

string length must be a value from 1 to 255 The length of a string in Pascal is limited to 255 characters. You are trying to declare a string with length greater than 255.

class identifier expected The variable isn't of type class.

method identifier expected This identifier is not a method.

function header doesn't match any method of this class You are defining a function as a class method, but no such function was declared in the class.

use extended syntax of DISPOSE and NEW to generate instances of classes If you have a pointer a to a class type, then the statement new(a) will not initialize the class (i.e. the constructor isn't called), although space will be allocated. you should issue the new(a,init) statement. This will allocate space, and call the constructor of the class.

file types must be var parameters You cannot specify files as value parameters, i.e. they must always be declared var parameters.

string exceeds line You forgot probably to include the closing ' in a string, so it occupies multiple lines.

illegal version of the unit: This unit was compiled with an earlier version of Free Pascal.

illegal floating point constant destructors can't have parameters

You are declaring a destructor with a parameter list. Destructor methods cannot have parameters. FAIL can be used in constructors only

You are using the FAIl instruction outside a constructor method. records fields can be aligned to 1,2 or 4 bytes only

You are specifying the {$PACKRECORDS n} with an illegal value for n. Only 1,2 or 4 are valid in this case.

too many $ENDIFs or $ELSEs Your {$IFDEF ..} and {$ENDIF} statements aren't balanced.

$ENDIF expected Your {$IFDEF ..} and {$ENDIF} statements aren't balanced.

illegal call by reference parameters can't generate DEF file

OS/2 only. The DEF file cannot be generated. all overloaded methods must be virtual if one is virtual:

If you declare overloaded methods in a class, then they should either all be virtual, or none. You cannot mix them.

overloaded methods which are virtual must have the same return type: If you declare virtual overloaded methods in a class definition, they must have the same return type.

all overloaded virtual methods must support exceptions if one support exceptions:

Free Pascal Manual Page 33

Page 34: Free Pascal Manual

If you declare overloaded virtual methods in a class, then they should either all support exceptions, or none. You cannot mix them.

EXPORT declared functions can't be called You are trying to call a procedure you declared as export. Due to the different calling scheme of Free Pascal and C, you cannot call such a function from within your Pascal program.

EXPORT declared functions can't be nested You cannot declare a function or procedure within a function or procedure that was declared as an export procedure.

methods can't be EXPORTed You cannot declare a procedure that is a method for an object as exported. That is, you methods cannot be called from a C program.

SELF is only allowed in methods You are trying to use the self parameter outside an object's method. Only methods get passed the self parameters.

call by var parameters have to match exactly When calling a function declared with var parameters, the variables in the function call must be of exactly the same type. There is no automatic type conversion.

class identifier expected The variable isn't of type class.

class isn't a super class of the current class When calling inherited methods, you are trying to call a method of a strange class. You can only call an inherited method of a parent class.

methods can be only in other methods called direct with type identifier of the class A construction like sometype.somemethod is only allowed in a method.

illegal type: pointer to class expected You specified an illegal type.

possible illegal call of constructor or destructor (doesn't match to this context) class should have one destructor only

You can declare only one destructor for a class. expression must be constructor call

When using the extended syntax of new, you must specify the constructor method of the class you are trying to create. The procedure you specified is not a constructor.

identifier idents no member When using the extended syntax of new, you must specify the constructor method of the class you are trying to create. The procedure you specified does not exist.

expression must be destructor call When using the extended syntax of dispose, you must specify the destructor method of the class you are trying to dispose of. The procedure you specified is not a destructor.

type conflict between set elements There is at least one set element which is of the wrong type, i.e. not of the set type.

illegal expression in set constructor type conflict between set elements

You are specifying elements of a different type for a set. illegal use of ':' expression type must be class or record type

The expression isn't of type class or record. the operator / isn't defined for integer, the result will be real, use DIV instead

When using the '/' operator in Free Pascal the result will be of type real, when used with integers. can't write PPU file

There is a problem when writing to the unit file. illegal order of record elements

When declaring a constant record, you specified the fields in the wrong order. the name of constructors must be INIT

You are declaring a constructor with a name which isn't init, and the -Ss switch is in effect. See the -Ss switch (See 5.1).

Page 34 Free Pascal Manual

Page 35: Free Pascal Manual

the name of constructors must be DONE You are declaring a constructor with a name which isn't done, and the -Ss switch is in effect. See the -Ss switch (See 5.1).

set element type mismatch The type of the element doesn't equal the set type.

illegal label declaration label not found

A goto label was encountered, but the label isn't declared. GOTO and LABEL are not supported (use command line switch -Sg)

You must compile a program which has labels and goto statements with the -Sg switch. By default, label and goto aren't supported.

set expected The variable or expression isn't of type set.

identifier isn't a label The identifier specified after the goto isn't of type label.

label already defined You're attempting to define a label two times. (i.e. you put the same label on two different places.)

label isn't defined: A label was declared, but not defined.

constructors and destructors must be methods You're declaring a procedure as destructor or constructor, when the procedure isn't a class method.

error when assembling An error occurred when assembling. This can have many causes.

identifier not used: This is a warning. The identifier was declared (locally or globally) but wasn't used (locally or globally).

functions with void return value can't return any value In Free Pascal, you can specify a return value for a function when using the exit statement. This error occurs when you try to do this with a procedure. Procedures cannot return a value.

Hmmm..., this code can't be much efficient You construction seems dubious to the compiler.

unreachable code You specified a loop which will never be executed. Example: while false do begin {.. code ...} end;

This overloaded function can't be local (must be exported) You are defining a overloaded function in the implementation part of a unit, but there is no corresponding declaration in the interface part of the unit.

It's not possible to overload this operator You are trying to overload an operator which cannot be overloaded.

Abstract methods can't be called direct Free Pascal understands the abstract keyword.

the mix of CLASSES and OBJECTS are not allowed You cannot use object and class intertwined.

macro buffer overflow while reading or expanding a macro Your macro or it's result was too long for the compiler.

keyword redefined as macro has no effect You cannot redefine keywords with macros.

extension of macros exceeds a deep of 16,perhaps there is a recursive macro definition (crashes the compiler)

When expanding a macro macros have been nested to a level of 16. ENDIF without IF(N)DEF

Your code contains more {$ENDIF} than {$IF(N)DEF} statements.

Free Pascal Manual Page 35

Page 36: Free Pascal Manual

user defined: A user defined warning occurred. see also the Programmer's guide\

linker: Duplicate symbol: Two global symbols in the code have the same name.

linker: Error while reading object file The linker couldn't read the object file (the assembled file).

linker: object file not found The linker didn't find the object file (the assembled file).

linker: illegal magic number in file: The linker cannot determine the type of a file it wants to link in. The type of a link file is specified using a magic number, which is some pre-defined constant, unique for each system.

The extended syntax of new or dispose isn't allowed for a class You cannot generate an instance of a class with the extended syntax of new. The constructor must be used for that. For the same reason, you cannot call Dispose to de-allocate an instance of a class, the destructor must be used for that.

To generate an instance of a class or an object with an abstract method isn't allowed You are trying to generate an instance of a class which has an abstract method that wasn't overridden.

Only virtual methods can be abstract You are declaring a method as abstract, when it isn't declared to be virtual.

Abstract methods shouldn't have any definition (with function body) Abstract methods can only be declared, you cannot implement them. They should be overridden by a descendant class.

can't call the assembler An error occurred when calling the assembler.

can't call o2obj An error occurred when calling the o to obj conversion program.

asm syntax error There is an error in the assembly language.

register name expected There is an error in the assembly language. The assembler expected a register and got something else.

asm size mismatch There is an error in the assembly language. The sizes of operands and registers don't match.

no instr match, There is an error in the assembly language. An unknown instruction was encountered.

can't compile unit: When trying to do a build, the compiler cannot compile one of the units.

Re-raise isn't possible there You are trying to raise an exception where it isn't allowed. You can only raise exceptions in an except block.

Syntax error while parsing a conditional compiling expression Evaluating a conditional compiling expression Keyword redefined as macro has no effect compiler switches aren't allowed in (* ... *) styled comments No DLL File specified Illegal open parameter Illegal floating point constant string types doesn't match, because of $V+ mode Only class methods can be referred with class references Only class methods can be accessed in class methods Constant and CASE types do not match The symbol can't be exported from a library A virtual method must be overridden using the OVERRIDE directive: There is no method in an ancestor class to be overridden:

Page 36 Free Pascal Manual

Page 37: Free Pascal Manual

No member is provided to access property Illegal symbol for property access Cannot write a protected field of an object range check error in set constructor or duplicate set element Pointer to class expected Operator is not overloaded Variable or type indentifier expected Assembler incompatible with function return value Procedure overloading is switched off Comparative operator must return a boolean value Use of unsupported feature! absolute can only be associated to ONE variable absolute can only be associated a var or const succ or pred on enums with assignments not possible Array properties aren't allowed at this point No property found to override Only one default property is allowed, found inherited default property in class The default property must be an array property Internal Error in SymTableStack() Error in type defenition Only static variables can be used in static methods or outside methods Invalid call to tvarsym.mangledname() illegal type declaration of set elements Forward class definition not resolved identifier idents no member The use of a far pointer isn't allowed there procedure call with stackframe ESP/SP Abstract methods can't be called directly Internal Error in getfloatreg(), allocation failure Unknown float type SecondVecn() base defined twice Extended cg68k not supported 32-bit unsigned not supported in MC68000 mode inline() Stack limit excedeed in local routineInternal Error in second

RUN TIME ERRORS

The Free Pascal Run-tim library generates the following errors at run-time: 1 Invalid function number

You tried to call a DOS function which doesn't exist. 2 File not found

You can get this error when you tried to do an operation on a file which doesn't exist. 3 Path not found

You can get this error when you tried to do an operation on a file which doesn't exist, or when you try to change to, or remove a directory that doesn't exist, or try to make a subdirectory of a subdirectory that doesn't exist.

4 Too many open files When attempting to open a file for reading or writing, you can get this error when your program has too many open files.

5 File access denied You don't have access to the specified file.

6 Invalid file handle If this happens, the file variable you are using is trashed; it indicates that your memory is corrupted.

Free Pascal Manual Page 37

Page 38: Free Pascal Manual

12 Invalid file access code This will happen if you do a reset or rewrite of a file when FileMode is invalid.

15 Invalid drive number The number given to the Getdir function specifies a non-existent disk.

16 Cannot remove current directory You get this if you try to remove the current diirectory.

17 Cannot rename across drives You cannot rename a file such that it would end up on another disk or partition.

100 Disk read error DOS only. An error occurred when reading from disk. Typically when you try to read past the end of a file.

101 Disk write error DOS only. Reported when the disk is full, and you're trying to write to it.

102 File not assigned This is reported by Reset, Rewrite, Append, Rename and Erase, if you call them with an unassigne function as a parameter.

103 File not open Reported by the following functions : Close , Read, Write, Seek, EOf, FilePos, FileSize, Flush, BlockRead, and BlockWrite if the file isn't open.

104 File not open for input Reported by Read, BlockRead, Eof, Eoln, SeekEof or SeekEoln if the file isn't opened with Reset.

105 File not open for output Reported by write if a text file isn't opened with Rewrite.

106 Invalid numeric format Reported when a non-numerice value is read from a text file, when a numeric value was expected.

150 Disk is write-protected (Critical error, DOS only.)

151 Bad drive request struct length (Critical error, DOS only.)

152 Drive not ready (Critical error, DOS only.)

154 CRC error in data (Critical error, DOS only.)

156 Disk seek error (Critical error, DOS only.)

157 Unknown media type (Critical error, DOS only.)

158 Sector Not Found (Critical error, DOS only.)

159 Printer out of paper (Critical error, DOS only.)

160 Device write fault (Critical error, DOS only.)

161 Device read fault (Critical error, DOS only.)

162 Hardware failure (Critical error, DOS only.)

200 Division by zero You are dividing a number by zero.

201 Range check error If you compiled your program with range checking on, then you can get this error in the following cases: An array was accessed with an index outside its declared range.You're trying to assign a value to a variable outside its range (for instance a enumerated type).

202 Stack overflow error

Page 38 Free Pascal Manual

Page 39: Free Pascal Manual

The stack has grown beyond itss maximum size. This error can easily occur if you have recursive functions.

203 Heap overflow error The heap has grown beyond its boundaries, ad you are rying to get more memory. Please note that Free Pascal provides a growing heap, i.e. the heap will try to allocate more memory if needed. However, if the heap has reached the maximum size allowed by the operating system or hardware, then you will get this error.

204 Invalid pointer operation This you will get if you call dispose or Freemem with an invalid pointer (notably, Nil)

205 Floating point overflow You are trying to use or produce too large real numbers.

206 Floating point underflow You are trying to use or produce too small real numbers.

207 Invalid floating point operation Can occur if you try to calculate the square root or logarithm of a negative number.

210 Object not initialized When compiled with range checking on, a program will report this error if you call a virtal method without having initialized the VMT.

211 Call to abstract method Your program tried to execute an abstract virtual method. Abstract methods should be overridden, and the overriding method should be called.

212 Stream registration error This occurs when an invalid type is registered in the objects unit.

213 Collection index out of range You are trying to access a collection item with an invalid index. (objects unit)

214 Collection overflow error The collection has reached its maximal size, and you are trying to add another element. (objects unit)

216 General Protection fault You are trying to access memory outside your appointed memory.

ASSEMBLER READER ERRORS.

This section lists the errors that are generated by the inline assembler reader. They are not the messages of the assembler itself.

General assembler errors

Divide by zero in asm evaluator This fatal error is reported when a constant assembler expressions does a division by zero.

Evaluator stack overflow, Evaluator stack underflow These fatal errors are reported when a constant assembler expression is too big to evaluate by the constant parser. Try reducing the number of terms.

Invalid numeric format in asm evaluator This fatal error is reported when a non-numeric value is detected by the constant parser. Normally this error should never occur.

Invalid Operator in asm evaluator This fatal error is reported when a mathematical operator is detected by the constant parser. Normally this error should never occur.

Unknown error in asm evaluator This fatal error is reported when an internal error is detected by the constant parser. Normally this error should never occur.

Invalid numeric value

Free Pascal Manual Page 39

Page 40: Free Pascal Manual

This warning is emitted when a conversion from octal,binary or hexadecimal to decimal is outside of the supported range.

Escape sequence ignored This error is emitted when a non ANSI C escape sequence is detected in a C string.

Asm syntax error - Prefix not found This occurs when trying to use a non-valid prefix instruction

Asm syntax error - Trying to add more than one prefix This occurs when you try to add more than one prefix instruction

Asm syntax error - Opcode not found You have tried to use an unsupported or unknown opcode

Constant value out of bounds This error is reported when the constant parser determines that the value you are using is out of bounds, either with the opcode or with the constant declaration used.

Non-label pattern contains @ This only applied to the m68k and Intel styled assembler, this is reported when you try to use a non-label identifier with a '@' prefix.

Internal error in Findtype() Internal Error in ConcatOpcode() Internal Errror converting binary Internal Errror converting hexadecimal Internal Errror converting octal Internal Error in BuildScaling() Internal Error in BuildConstant() internal error in BuildReference() internal error in HandleExtend() Internal error in ConcatLabeledInstr()

  These errors should never occur, if they do then you have found a new bug in the assembler parsers. Please contact one of the developers.

Opcode not in table, operands not checked This warning only occurs when compiling the system unit, or related files. No checking is performed on the operands of the opcodes.

@CODE and @DATA not supported This Turbo Pascal construct is not supported.

SEG and OFFSET not supported This Turbo Pascal construct is not supported.

Modulo not supported Modulo constant operation is not supported.

Floating point binary representation ignored Floating point hexadecimal representation ignored Floating point octal representation ignored

These warnings occur when a floating point constant are declared in a base other then decimal. No conversion can be done on these formats. You should use a decimal representation instead.

Identifier supposed external This warning occurs when a symbol is not found in the symolb table, it is therefore considered external.

Functions with void return value can't return any value in asm code Only routines with a return value can have a return value set.

Error in binary constant Error in octal constant Error in hexadecimal constant Error in integer constant

  These errors are reported when you tried using an invalid constant expression, or that the value is out of range.

Invalid labeled opcode Asm syntax error - error in reference Invalid Opcode

Page 40 Free Pascal Manual

Page 41: Free Pascal Manual

Invalid combination of opcode and operands Invalid size in reference Invalid middle sized operand Invalid three operand opcode Assembler syntax error Invalid operand type

You tried using an invalid combination of opcode and operands, check the syntax and if you are sure it is correct, please contact one of the developers.

Unknown identifier The identifier you are trying to access does not exist, or is not within the current scope.

Trying to define an index register more than once Trying to define a segment register twice Trying to define a base register twice

You are trying to define an index/segment register more then once. Invalid field specifier

The record or object field you are trying to access does not exist, or is incorrect. Invalid scaling factor Invalid scaling value Scaling value only allowed with index

Allowed scaling values are 1,2,4 or 8. Cannot use SELF outside a method

You are trying to access the SELF identifier for objects outside a method. Invalid combination of prefix and opcode

This opcode cannot be prefixed by this instruction Invalid combination of override and opcode

This opcode cannot be overriden by this combination Too many operands on line

At most three operand instructions exist on the m68k, and i386, you are probably trying to use an invalid syntax for this opcode.

Duplicate local symbol You are trying to redefine a local symbol, such as a local label.

Unknown label identifer Undefined local symbol local symbol not found inside asm statement

This label does not seem to have been defined in the current scope Assemble node syntax error Not a directive or local symbol

The assembler statement is invalid, or you are not using a recognized directive.

I386 specific errors

repeat prefix and a segment override on <= i386 may result in errors if an interrupt occurs A problem with interrupts and a prefix instruction may occur and may cause false results on 386 and earlier computers.

Fwait can cause emulation problems with emu387 This warning is reported when using the FWAIT instruction, it can cause emulation problems on systems which use the em387.dxe emulator.

You need GNU as version >= 2.81 to compile this MMX code MMX assembler code can only be compiled using GAS v2.8.1 or later.

NEAR ignored FAR ignored

  NEAR and FAR are ignored in the intel assemblers, but are still accepted for compatiblity with the 16-bit code model.

Invalid size for MOVSX/MOVZX 16-bit base in 32-bit segment

Free Pascal Manual Page 41

Page 42: Free Pascal Manual

16-bit index in 32-bit segment 16-bit addressing is not supported, you must use 32-bit addressing.

Constant reference not allowed It is not allowed to try to address a constant memory address in protected mode.

Segment overrides not supported Intel style (eg: rep ds stosb) segment overrides are not support by the assembler parser.

Expressions of the form [sreg:reg...] are currently not supported To access a memory operand in a different segment, you should use the sreg:[reg...] snytax instead of [sreg:reg...]

Size suffix and destination register do not match In intel AT&T syntax, you are using a register size which does not concord with the operand size specified.

Invalid assembler syntax. No ref with brackets Trying to use a negative index register Local symbols not allowed as references Invalid operand in bracket expression Invalid symbol name: Invalid Reference syntax Invalid string as opcode operand: Null label references are not allowed Using a defined name as a local label Invalid constant symbol Invalid constant expression / at beginning of line not allowed NOR not supported Invalid floating point register name Invalid floating point constant: Asm syntax error - Should start with bracket Asm syntax error - register: Asm syntax error - in opcode operand Invalid String expression Constant expression out of bounds Invalid or missing opcode Invalid real constant expression Parenthesis are not allowed Invalid Reference Cannot use __SELF outside a method Cannot use __OLDEBP outside a nested procedure Invalid segment override expression Strings not allowed as constants Switching sections is not allowed in an assembler block Invalid global definition Line separator expected Invalid local common definition Invalid global common definition assembler code not returned to text invalid opcode size Invalid character: < Invalid character: > Unsupported opcode Invalid suffix for intel assembler Extended not supported in this mode Comp not supported in this mode Invalid Operand: Override operator not supported

Page 42 Free Pascal Manual

Page 43: Free Pascal Manual

m68k specific errors.

Increment and Decrement mode not allowed together You are trying to use dec/inc mode together.

Invalid Register list in movem/fmovem The register list is invalid, normally a range of registers should be separated by - and individual registers should be separated by a slash.

Invalid Register list for opcode 68020+ mode required to assemble

Free Pascal Manual Page 43

Page 44: Free Pascal Manual

THE FLOATING POINT COPROCESSOR EMULATORIn this appendix we note some caveats when using the floating point emulator on GO32V2 systems. Under GO32V1 systems, all is as described in the installation section. Q: I don't have an 80387. How do I compile and run floating point programs under GO32V2? Q: What shall I install on a target machine which lacks hardware floating-point support? A : Programs which use floating point computations and could be run on machines without an 80387 should be allowed to dynamically load the emu387.dxe file at run-time if needed. To do this you must link the emu387 unit to your exectuable program, for example: Program MyFloat;

Uses emu387;

var r: real; Begin r:=1.0; WriteLn(r); end.Emu387 takes care of loading the dynamic emulation point library. You should always add emulation when you distribute floating-point programs. A few users reported that the emulation won't work for them unless they explicitly tell DJGPP there is no x87 hardware, like this: set 387=N set emu387=c:/djgpp/bin/emu387.dxeThere is an alternative FP emulator called WMEMU. It mimics a real coprocessor more closely. WARNING: We strongly suggest that you use WMEMU as FPU emulator, since emu387.dxe does not emulate all the instructions which are used by the Run-Time Libary such as FWAIT. Q: I have an 80387 emulator installed in my AUTOEXEC.BAT, but DJGPP-compiled floating point programs still doesn't work. Why? A : DJGPP switches the CPU to protected mode, and the information needed to emulate the 80387 is different. Not to mention that the exceptions never get to the real-mode handler. You must use emulators which are designed for DJGPP. Apart of emu387 and WMEMU, the only other emulator known to work with DJGPP is Q87 from QuickWare. Q87 is shareware and is available from the QuickWare Web site. Q: I run DJGPP in an OS/2 DOS box, and I'm told that OS/2 will install its own emulator library if the CPU has no FPU, and will transparently execute FPU instructions. So why won't DJGPP run floating-point code under OS/2 on my machine? A : OS/2 installs an emulator for native OS/2 images, but does not provide FPU emulation for DOS sessions.

A sample gdb.ini file

  Here you have a sample gdb.ini file listing, which gives better results when using gdb. Under LINUX you should put this in a .gdbinit file in your home directory or the current directory.. set print demangle offset gnutarget autoset verbose onset complaints 1000dir ./rtl/dosv2set language c++set print vtbl onset print object onset print sym onset print pretty ondisp /i $eip

Page 44 Free Pascal Manual

Page 45: Free Pascal Manual

define pstset $pos=&$arg0set $strlen = {byte}$posprint {char}&$arg0.st@($strlen+1)end

document pst Print out a pascal stringend

Free Pascal Manual Page 45

Page 46: Free Pascal Manual

Page 46 Free Pascal Manual

Page 47: Free Pascal Manual

FREE PASCAL :PROGRAMMER’S GUIDE

Free Pascal Manual Page 47

Page 48: Free Pascal Manual

Contents Compiler directives

Local directives $F : Far or near functions $I : Input/Output checking $I : Include file $L : Link object file $I386_XXX : Specify assembler format $MMX : MMX support $OUTPUT_FORMAT : Specify the output format $V : Var-string checking

Global directives $A : Align Data $B : Complete boolean evaluation $D : Debugging symbols $E : Emulation of coprocessor $G : Generate 80286 code $L : Local symbol information $N : Numeric processing $O : Overlay code generation $Q : Overflow checking $R : Range checking $S : Stack checking $X : Extended syntax

Using conditionals, Messages and macros Conditionals Messages Macros

Using assembly language Intel syntax AT&T Syntax Calling mechanism Telling the compiler what registers have changed

Linking issues Declaring an external function or procedure Explicitly linking an object file in your program Linking your program to a library Making a shared library

Adapting your code Compiling libraries Moving units into a library Unit searching strategy

Objects Constructor and Destructor calls Memory storage of objects The Virtual Method Table

Generated code Units Programs

MMX support What is it about ? Saturation support Restrictions of MMX support

Page 48 Free Pascal Manual

Page 49: Free Pascal Manual

Supported MMX operations Optimizing MMX support

Memory issues The 32-bit model. The stack

The heap grows Using Blocks Using the split heap

Accessing DOS memory under the Go32 extender Anatomy of a unit file List of compiler source files Compiler limits Optimizing techniques used in the compiler.

Free Pascal Manual Page 49

Page 50: Free Pascal Manual

ABOUT THIS DOCUMENT

This is the programmer's manual for Free Pascal. It describes some of the peculiarities of the Free Pascal compiler, and provides a glimp of how the compiler generates its code, and how you can change the generated code. It will not, however, provide you with a detailed account of the inner workings of the compiler, nor will it tell you how to use the compiler (described in the Users' guide\). It also will not describe the inner workings of the Run-Time Library (RTL). The best way to learn about the way the RTL is implemented is from the sources themselves. The things described here are useful if you want to do things which need greater flexibility than the standard Pascal language constructs. (described in the Reference guide\) Since the compiler is continuously under development, this document may get out of date. Wherever possible, the information in this manual will be updated. If you find something which isn't correct, or you think something is missing, feel free to contact me.

LOCAL DIRECTIVES

  Local directives have no command-line counterpart. They influence the compiler's behaviour from the moment they're encountered until the moment another switch annihilates their behaviour, or the end of the unit or program is reached.

$F : Far or near functions

This directive is recognized for compatibility with Turbo Pascal. Under the 32-bit programming model, the concept of near and far calls have no meaning, hence the directive is ignored. A warning is printed to the screen, telling you so. As an example, : the following piece of code : {$F+}

Procedure TestProc;

begin Writeln ('Hello From TestProc');end;

begin testProcend.Generates the following compiler output: malpertuus: >pp -vw testfCompiler: ppc386Units are searched in: /home/michael;/usr/bin/;/usr/lib/ppc/0.9.1/linuxunitsTarget OS: LinuxCompiling testf.pptestf.pp(1) Warning: illegal compiler switch7739 kB freeCalling assembler...Assembled...Calling linker...12 lines compiled, 1.00000000000000E+0000You can see that the verbosity level was set to display warnings.

Page 50 Free Pascal Manual

Page 51: Free Pascal Manual

If you declare a function as Far (this has the same effect as setting it between {$F+}...{$F-} directives), the compiler also generates a warning : testf.pp(3) Warning: FAR ignoredThe same story is true for procedures declared as Near. The warning displayed in that case is: testf.pp(3) Warning: NEAR ignored

$I : Input/Output checking

The {$I-} directive tells the compiler not to generate input/output checking code in your program. If you compile using the -Ci compiler switch, the Free Pascal compiler inserts input/output checking code after every input/output call in your program. If an error occurred during input or output, then a run-time error will be generated. Use this switch if you wish to avoid this behavior. If you still want to check if something went wrong, you can use the IOResult function to see if everything went without problems. Conversely, {$I+} will turn error-checking back on, until another directive is encountered which turns it off again. The most common use for this switch is to check if the opening of a file went without problems, as in the following piece of code: ...assign (f,'file.txt');{$I-}rewrite (f);{$I+}if IOResult<>0 then begin Writeln ('Error opening file : "file.txt"'); exit end;...

$I : Include file

The {$I filename} directive tells the compiler to read further statements from the file filename. The statements read there will be inserted as if they occurred in the current file. The compiler will append the .pp extension to the file if you don't specify an extension yourself. Do not put the filename between quotes, as they will be regarded as part of the file's name. You can nest included files, but not infinitely deep. The number of files is restricted to the number of file descriptors available to the Free Pascal compiler. Contrary to Turbo Pascal, include files can cross blocks. I.e. you can start a block in one file (with a Begin keyword) and end it in another (with a End keyword). The smallest entity in an include file must be a token, i.e. an identifier, keyword or operator.

$L : Link object file

The {$L filename} directive tells the compiler that the file filename should be linked to your program. You can only use this directive in a program. If you do use it in a unit, the compiler will not complain, but simply ignores the directive. The compiler will not look for the file in the unit path. The name will be passed to the linker exactly as you've typed it. Since the files name is passed directly to the linker, this means that on LINUX systems, the name is case sensitive, and must be typed exactly as it appears on your system. Remark : Take care that the object file you're linking is in a format the linker understands. Which format this is, depends on the platform you're on. Typing ld on th command line gives a list of formats ld knows about.

Free Pascal Manual Page 51

Page 52: Free Pascal Manual

You can pass other files and options to the linker using the -k command-line option. You can specify more than one of these options, and they will be passed to the linker, in the order that you specified them on the command line, just before the names of the object files that must be linked.

$I386_XXX : Specify assembler format

This switch informs the compiler what kind of assembler it can expect in an asm block. The XXX should be replaced by one of the following: att

Indicates that asm blocks contain AT&T syntax assembler. intel

Indicates that asm blocks contain Intel syntax assembler. direct

Tells the compiler that asm blocks should be copied directly to the assembler file. These switches are local, and retain their value to the end of the unit that is compiled, unless they are replaced by another directive of the same type. The command-line switch that corresponds to this switch is -R.

$MMX : MMX support

As of version 0.9.8, Free Pascal supports optimization for the MMX Intel processor (see also 7). This optimizes certain code parts for the MMX Intel processor, thus greatly improving speed. The speed is noticed mostly when moving large amounts of data. Things that change are

Data with a size that is a multiple of 8 bytes is moved using the movq assembler instruction, which moves 8 bytes at a time

When MMX support is on, you aren't allowed to do floating point arithmetic. You are allowed to move floating point data, but no arithmetic can be done. If you wish to do floating point math anyway, you must first switch of MMX support and clear the FPU using the emms function of the cpu unit. The following example will make this more clear: Program MMXDemo;

uses cpu;

var d1 : double; a : array[0..10000] of double; i : longint;

begin d1:=1.0;{$mmx+} { floating point data is used, but we do _no_ arithmetic } for i:=0 to 10000 do a[i]:=d2; { this is done with 64 bit moves }{$mmx-} emms; { clear fpu } { now we can do floating point arithmetic } ....end.See, however, the chapter on MMX (7) for more information on this topic.

$OUTPUT_FORMAT : Specify the output format

{$OUTPUT_FORMAT format} has the same functionality as the -A command-line option : It tells

Page 52 Free Pascal Manual

Page 53: Free Pascal Manual

the compiler what kind of object file must be generated. You can specify this switch only befor the Program or Unit clause in your source file. The different kinds of formats are shown in table (1.1).   Table 1.1: Formats generated by the compiler

Switch value Generated format att AT&T assembler file. o Unix object file.obj OMF file.wasm assembler for the Watcom assembler.

$V : Var-string checking

When in the + state, the compiler checks that strings passed as parameters are of the same, identical, string type as the declared parameters of the procedure.

Free Pascal Manual Page 53

Page 54: Free Pascal Manual

COMPILER DIRECTIVES

  Free Pascal supports compiler directives in your source file. They are not the same as Turbo Pascal directives, although some are supported for compatibility. There is a distinction between local and global directives; local directives take effect from the moment they are encountered, global directives have an effect on all of the compiled code.

Local directives Global directives

GLOBAL DIRECTIVES

  Global directives affect the whole of the compilation process. That is why they also have a command - line counterpart. The command-line counterpart is given for each of the directives.

$A : Align Data

This switch is recognized for Turbo Pascal Compatibility, but is not yet implemented. The alignment of data will be different in any case, since Free Pascal is a 32-bit compiler.

$B : Complete boolean evaluation

This switch is understood by the Free Pascal compiler, but is ignored. The compiler always uses shortcut evaluation, i.e. the evaluation of a boolean expression is stopped once the result of the total exression is known with certainty. So, in the following example, the function Bofu, which has a boolean result, will never get called. If False and Bofu then ...

$D : Debugging symbols

When this switch is on, the compiler inserts GNU debugging information in the executable. The effect of this switch is the same as the command-line switch -g. By default, insertion of debugging information is off.

$E : Emulation of coprocessor

This directive controls the emulation of the coprocessor. On the i386 processor, it is supported for compatibility with Turbo Pascal. The compiler itself doesn't do the emulation of the coprocessor. Under DOS, the DOS extender does this, and under LINUX, the kernel takes care of the coprocessor support. If you use the Motorola 680x0 version, then the switch is recognized, as there is no extender to emulate the coprocessor, so the compiler must do that by itself. There is no command-line counterpart for this directive.

$G : Generate 80286 code

This option is recognised for Turbo Pascal cmpatibility, but is ignored, because the compiler needs at least a 386 or higher class processor.

Page 54 Free Pascal Manual

Page 55: Free Pascal Manual

$L : Local symbol information

This switch (not to be confused with the {$L file} file linking directive) is recognised for Turbo Pascal compatibility, but is ignored. generation of symbol information is controlled by the $D switch.

$N : Numeric processing

This switch is recognised for Turbo Pascal compatibility, but is otherwise ignored, since the compiler always uses the coprocessor for floating point mathematics.

$O : Overlay code generation

This switch is recognised for Turbo Pascal compatibility, but is otherwise ignored, since the compiler requires a 386 or higher computer, with at least 4 Mb. of ram.

$Q : Overflow checking

The {$Q+} directive turns on integer overflow checking. This means that the compiler inserts code to check for overflow when doing computations with an integer. When an overflow occurs, the run-time library will print a message Overflow at xxx, and exit the program with exit code 1. Using the {$Q-} switch switches off the overflow checking code generation. The generation of overflow checking code can also be controlled using the -Co command line compiler option (see Users' guide\).

$R : Range checking

By default, the computer doesn't generate code to check the ranges of array indices, enumeration types, subrange types, etc. Specifying the {$R+} switch tells the computer to generate code to check these indices. If, at run-time, an index or enumeration type is specified that is out of the declared range of the compiler, then a run-time error is generated, and the program exits with exit code 1. The {$R-} switch tells the compiler not to generate range checking code. This may result in faulty program behaviour, but no run-time errors will be generated. Remark: this has not been implemented completely yet.

$S : Stack checking

The {$S+} directive tells the compiler to generate stack checking code. This generates code to check if a stack overflow occurred, i.e. to see whether the stack has grown beyond its maximally allowed size. If the stack grows beyond the maximum size, then a run-time error is generated, and the program will exit with exit code 1. Specifying {$S-} will turn generation of stack-checking code off. There is no command-line switch which is equivalent to this directive. Remark: In principle, the stack is almost unlimited, i.e. limited to the total free amount of memory on the computer.

$X : Extended syntax

Extended syntax allows you to drop the result of a function. This means that you can use a function call as if it were a procedure. Standard this feature is on. You can switch it off using the {$X-} directive. The following, for instance, will not compile : function Func (var Arg : sometype) : longint;

Free Pascal Manual Page 55

Page 56: Free Pascal Manual

begin... { declaration of Func }end;

...

{$X-}Func (A);The reason this construct is supported is that you may wish to call a function for certain side-effects it has, but you don't need the function result. In this case you don't need to assign the function result, saving you an extra variable. The command-line compiler switch -Sa1 has the same effect as the {$X+} directive.

Page 56 Free Pascal Manual

Page 57: Free Pascal Manual

USING CONDITIONALS, MESSAGES AND MACROS  The Free Pascal compiler supports conditionals as in normal Turbo Pascal. It does, however, more than that. It allows you to make macros which can be used in your code, and it allows you to define messages or errors which will be displayed when compiling.

Conditionals Messages Macros

CONDITIONALS

  The rules for using conditional symbols are the same as under Turbo Pascal. Defining a symbol goes as follows: {$Define Symbol }From this point on in your code, the compiler know the symbol Symbol Symbols are, like the Pascal language, case insensitive. You can also define a symbol on the command line. the -dSymbol option defines the symbol Symbol. You can specify as many symbols on the command line as you want. Undefining an existing symbol is done in a similar way: {$Undef Symbol }If the symbol didn't exist yet, this doesn't do anything. If the symbol existed previously, the symbol will be erased, and will not be recognized any more in the code following the {$Undef ...} statement. You can also undefine symbols from the command line with the -u command-line switch.. To compile code conditionally, depending on whether a symbol is defined or not, you can enclose the code in a {$ifdef Symbol} .. {$endif} pair. For instance the following code will never be compiled : {$Undef MySymbol}{$ifdef Mysymbol} DoSomething; ...{$endif}Similarly, you can enclose your code in a {$Ifndef Symbol} .. {$endif} pair. Then the code between the pair will only be compiled when the used symbol doesn't exist. For example, in the following example, the call to the DoSomething will always be compiled: {$Undef MySymbol}{$ifndef Mysymbol} DoSomething; ...{$endif}You can combine the two alternatives in one structure, namely as follows {$ifdef Mysymbol} DoSomething;{$else} DoSomethingElse{$endif}In this example, if MySymbol exists, then the call to DoSomething will be compiled. If it doesn't exist, the call to DoSomethingElse is compiled. The Free Pascal compiler defines some symbols before starting to compile your program or unit. You can use these symbols to differentiate between different versions of the compiler, and between different compilers. In table (2.1), a list of pre-defined symbols is given. In that table, you should change v with the version number of the compiler you're using, r with the release number and p with the patch-number

Free Pascal Manual Page 57

Page 58: Free Pascal Manual

of the compiler. 'OS' needs to be changed by the type of operating system. Currently this can be one of DOS, GO32V2, LINUX, OS2 or WIN32. This symbol is undefined if you specify a target that is different from the platform you're compiling on. the -TSomeOS option on the command line will define the SomeOS symbol, and will undefined the existing platform symbol.   Table 2.1: Symbols defined by the compiler.

Free VERv

VERv_r

VERv_r_p

OS As an example : Version 0.9.1 of the compiler, running on a Linux system, defines the following symbols before reading the command line arguments: FPC, VER0, VER0_9, VER0_9_1 and LINUX. Specifying -TOS2 on the command-line will undefine the LINUX symbol, and will define the OS2 symbol. Remark: Symbols, even when they're defined in the interface part of a unit, are not available outside that unit. Free Pascal supports the {$IFOPT } directive for Turbo Pascal compatibility, but doesn't act on it. It always rejects the condition, so code between {$IFOPT } and {$Endif} is never compiled. Except for the Turbo Pascal constructs, from version 0.9.8 and higher, the Free Pascal compiler also supports a stronger conditional compile mechanism: The {$If } construct. The prototype of this construct is as follows : {$If expr} CompileTheseLines;{$else} BetterCompileTheseLines;{$endif}In this directive expr is a Pascal expression which is evaluated using strings, unless both parts of a comparision can be evaluated as numbers, in which case they are evaluated using numbers. If the complemete expression evaluates to '0', then it is considered false and rejected. Otherwise it is considered true and accepted. This may have unsexpected consequences : {$If 0}Will evaluate to False and be rejected, while {$If 00}Will evaluate to True. You can use any Pascal operator to construct your expression : =, <>, >, <, >=, <=, AND, NOT, OR and you can use round brackets to change the precedence of the operators. The following example shows you many of the possibilities: {$ifdef fpc}

var y : longint;{$else fpc}

var z : longint;{$endif fpc}

var x : longint;

begin

{$if (fpc_version=0) and (fpc_release>6) and (fpc_patch>4)}

Page 58 Free Pascal Manual

Page 59: Free Pascal Manual

{$info At least this is version 0.9.5}{$else}{$fatalerror Problem with version check}{$endif}

{$define x:=1234}{$if x=1234}{$info x=1234}{$else}{$fatalerror x should be 1234}{$endif}

{$if 12asdf and 12asdf}{$info $if 12asdf and 12asdf is ok}{$else}{$fatalerror $if 12asdf and 12asdf rejected}{$endif}

{$if 0 or 1}{$info $if 0 or 1 is ok}{$else}{$fatalerror $if 0 or 1 rejected}{$endif}

{$if 0}{$fatalerror $if 0 accepted}{$else}{$info $if 0 is ok}{$endif}

{$if 12=12}{$info $if 12=12 is ok}{$else}{$fatalerror $if 12=12 rejected}{$endif}

{$if 12<>312}{$info $if 12<>312 is ok}{$else}{$fatalerror $if 12<>312 rejected}{$endif}

{$if 12<=312}{$info $if 12<=312 is ok}{$else}{$fatalerror $if 12<=312 rejected}{$endif}

{$if 12<312}{$info $if 12<312 is ok}{$else}{$fatalerror $if 12<312 rejected}{$endif}

{$if a12=a12}

Free Pascal Manual Page 59

Page 60: Free Pascal Manual

{$info $if a12=a12 is ok}{$else}{$fatalerror $if a12=a12 rejected}{$endif}

{$if a12<=z312}{$info $if a12<=z312 is ok}{$else}{$fatalerror $if a12<=z312 rejected}{$endif}

{$if a12<z312}{$info $if a12<z312 is ok}{$else}{$fatalerror $if a12<z312 rejected}{$endif}

{$if not(0)}{$info $if not(0) is OK}{$else}{$fatalerror $if not(0) rejected}{$endif}

{$info *************************************************}{$info * Now have to follow at least 2 error messages: *}{$info *************************************************}

{$if not(0}{$endif}

{$if not(<}{$endif}

end.As you can see from the example, this construct isn't useful when used with normal symbols, but it is if you use macros, which are explained in section (2.3), they can be very useful. When trying this example, you must switch on macro support, with the -Sm command-line switch.

MESSAGES

  Free Pascal lets you define normal, warning and error messages in your code. Messages can be used to display useful information, such as copyright notices, a list of symbols that your code reacts on etc. Warnings can be used if you think some part of your code is still buggy, or if you think that a certain combination of symbols isn't useful. In general anything which may cause problems when compiling. Error messages can be useful if you need a certain symbol to be defined to warn that a certain variable isn't defined or so, or when the compiler version isn't suitable for your code. The compiler treats these messages as if they were generated by the compiler. This means that if you haven't turned on warning messages, the warning will not e displayed. Errors are always displayed, and the compiler stops as if an error had occurred. For messages, the syntax is as follows : {$Message Message text }Or {$Info Message text }

Page 60 Free Pascal Manual

Page 61: Free Pascal Manual

For notes: {$Note Message text }For warnings: {$Warning Warning Message text }For errors : {$Error Error Message text }Lastly, for fatal errors : {$FatalError Error Message text }or {$Stop Error Message text }The difference between $Error and $FatalError or $Stop messages is that when the compiler encounters an error, it still continues to compile. With a fatal error, the compiler stops. Remark : You cannot use the '}' character in your message, since this will be treated as the closing brace of the message. As an example, the following piece of code will generate an error when the symbol RequiredVar isn't defined: {$ifndef RequiredVar}{$Error Requiredvar isn't defined !}{$endif}But the compiler will continue to compile. It will not, however, generate a unit file or a program (since an error occurred).

MACROS

  Macros are very much like symbols in their syntax, the difference is that macros have a value whereas a symbol simply is defined or is not defined. If you want macro support, you need to specify the -Sm command-line switch, otherwise your macro will be regarded as a symbol. Defining a macro in your program is done in the same way as defining a symbol; in a {$define } preprocessor statement: {$define ident:=expr}If the compiler encounters ident in the rest of the source file, it will be replaced immediately by expr. This replacement works recursive, meaning that when the compiler expanded one of your macros, it will look at the resulting expression again to see if another replacement can be made. You need to be careful with this, because an infinite loop can occur in this manner. Here are two examples which illustrate the use of macros: {$define sum:=a:=a+b;}...sum { will be expanded to 'a:=a+b;' remark the absence of the semicolon}...{$define b:=100}sum { Will be expanded recursively to a:=a+100; } ...The previous example could go wrong : {$define sum:=a:=a+b;}...sum { will be expanded to 'a:=a+b;' remark the absence of the semicolon}...{$define b=sum} { DON'T do this !!!}sum { Will be infinitely recursively expanded... } ...On my system, the last example results in a heap error, causing the compiler to exit with a run-time error 203. Remark: Macros defined in the interface part of a unit are not available outside that unit ! They can just

Free Pascal Manual Page 61

Page 62: Free Pascal Manual

be used as a notational convenience, or in conditional compiles. By default, from version 0.9.8 of the compiler on, the compiler predefines three macros, containing the version number, the release number and the patch number. They are listed in table (2.2).   Table 2.2: Predefined macros

Symbol Contains FPC_VERSION The version number of the compiler. FPC_RELEASE The release number of the compiler. FPC_PATCH The patch number of the compiler.

Remark: Don't forget that macros support isn't on by default. You need to compile with the -Sm command-line switch.

Page 62 Free Pascal Manual

Page 63: Free Pascal Manual

USING ASSEMBLY LANGUAGE

  Free Pascal supports inserting of assembler instructions in your code. The mechanism for this is the same as under Turbo Pascal. There are, however some substantial differences, as will be explained in the following.

Intel syntax AT&T Syntax Calling mechanism Telling the compiler what registers have changed

INTEL SYNTAX  As of version 0.9.7, Free Pascal supports Intel syntax in it's asm blocks. The Intel syntax in your asm block is converted to AT&T syntax by the compiler, after which it is inserted in the compiled source. The supported assembler constructs are a subset of the normal assembly syntax. In what follows we specify what constructs are not supported in Free Pascal, but which exist in Turbo Pascal:

The TBYTE qualifier is not supported. The & identifier override is not supported. The HIGH operator is not supported. The LOW operator is not supported. The OFFSET and SEG operators are not supported. use LEA and the various Lxx

instructions instead. Expressions with constant strings are not allowed. Access to record fields via parenthesis is not allowed Typecasts with normal pascal types are not allowed, only recognized assembler typecasts are

allowed.Example: mov al, byte ptr MyWord -- allowed,mov al, byte(MyWord) -- allowed,mov al, shortint(MyWord) -- not allowed.

Pascal type typecasts on constants are not allowed. Example: const s= 10; const t = 32767;in Turbo Pascal: mov al, byte(s) -- useless typecast.mov al, byte(t) -- syntax error!In this parser, either of those cases will give out a syntax error.

Constant references expressions with constants only are not allowed (in all cases they do not work in protected mode, under linux i386). Examples: mov al,byte ptr ['c'] -- not allowed.mov al,byte ptr [100h] -- not allowed.(This is due to the limitation of Turbo Assembler).

Brackets within brackets are not allowed Expressions with segment overrides fully in brackets are presently not supported, but they

can easily be implemented in BuildReference if requested. Example: mov al,[ds:bx] -- not alloweduse instead: mov al,ds:[bx]

Possible allowed indexing are as follows: Sreg:[REG+REG*SCALING+/-disp]

Free Pascal Manual Page 63

Page 64: Free Pascal Manual

SReg:[REG+/-disp] SReg:[REG] SReg:[REG+REG+/-disp] SReg:[REG+REG*SCALING]

Where Sreg is optional and specifies the segment override. Notes: 1. The order of terms is important contrary to Turbo Pascal.2. The Scaling value must be a value, and not an identifier to a symbol.

Examples: const myscale = 1;...mov al,byte ptr [esi+ebx*myscale] -- not allowed.use: mov al, byte ptr [esi+ebx*1]

Possible variable identifier syntax is as follows: (Id = Variable or typed constant identifier.) 1. ID2. [ID]3. [ID+expr]4. ID[expr]

Possible fields are as follow: 1. ID.subfield.subfield ...2. [ref].ID.subfield.subfield ...3. [ref].typename.subfield ...

Local Labels: Contrary to Turbo Pascal, local labels, must at least contain one character after the local symbol indicator.Example: @: -- not alloweduse instead, for example: @1: -- allowed

Contrary to Turbo Pascal local references cannot be used as references, only as displacements. example: lds si,@mylabel -- not allowed

Contrary to Turbo Pascal, SEGCS, SEGDS, SEGES and SEGSS segment overrides are presently not supported. (This is a planned addition though).

Contrary to Turbo Pascal where memory sizes specifiers can be practically anywhere, the Free Pascal Intel inline assembler requires memory size specifiers to be outside the brackets. example: mov al,[byte ptr myvar] -- not allowed.use: mov al,byte ptr [myvar] -- allowed.

Base and Index registers must be 32-bit registers. (limitation of the GNU Assembler). XLAT is equivalent to XLATB. Only Single and Double FPU opcodes are supported. Floating point opcodes are currently not supported (except those which involve only floating

point registers). The Intel inline assembler supports the following macros : @Result

represents the function result return value. Self

represents the object method pointer in methods.

AT&T SYNTAX  Free Pascal uses the gnu as assembler to generate its object files. Since the gnu assembler uses AT&T

Page 64 Free Pascal Manual

Page 65: Free Pascal Manual

assembly syntax, the code you write should use the same syntax. The differences between AT&T and Intel syntax as used in Turbo Pascal are summarized in the following:

The opcode names include the size of the operand. In general, one can say that the AT&T opcode name is the Intel opcode name, suffixed with a 'l', 'w' or 'b' for, respectively, longint (32 bit), word (16 bit) and byte (8 bit) memory or register references. As an example, the Intel construct 'mov al bl is equivalent to the AT&T style 'movb %bl,%al' instruction.

AT&T immediate operands are designated with '$', while Intel syntax doesn't use a prefix for immediate operands. Thus the Intel construct 'mov ax, 2' becomes 'movb $2, %al' in AT&T syntax.

AT&T register names are preceded by a '%' sign. They are undelimited in Intel syntax. AT&T indicates absolute jump/call operands with '*', Intel syntax doesn't delimit these

addresses. The order of the source and destination operands are switched. AT&T syntax uses 'Source,

Dest', while Intel syntax features 'Dest, Source'. Thus the Intel construct 'add eax, 4' transforms to 'addl $4, %eax' in the AT&T dialect.

Immediate long jumps are prefixed with the 'l' prefix. Thus the Intel 'call/jmp section:offset' is transformed to 'lcall/ljmp $section,$offset'. Similarly the far return is 'lret', instead of the Intel 'ret far'.

Memory references are specified differently in AT&T and Intel assembly. The Intel indirect memory reference

Section:[Base + Index*Scale + Offs] is written in AT&T syntax as :

Section:Offs(Base,Index,Scale) Where Base and Index are optional 32-bit base and index registers, and Scale is used to multiply Index. It can take the values 1,2,4 and 8. The Section is used to specify an optional section register for the memory operand.

More information about the AT&T syntax can be found in the as manual, although the following differences with normal AT&T assembly must be taken into account :

Only the following directives are presently supported: .byte .word .long .ascii .asciz .globl

The following directives are recognized but are not supported: .align .lcomm

Eventually they will be supported. Directives are case sensitive, other identifiers are not case sensitive. Contrary to GAS local labels/symbols must start with .L The nor operator '!' is not supported. String expressions in operands are not supported. Constant expressions which represent memory references are not allowed even though

constant immediate value expressions are supported. examples: const myid = 10;...movl $myid,%eax -- allowedmovl myid(%esi),%eax -- not allowed.

When the .globl directive is found, the symbol following it is made public and is immediately emitted. Therefore label names with this name will be ignored.

Only Single and Double FPU opcodes are supported. The AT&T inline assembler supports the following macros :

Free Pascal Manual Page 65

Page 66: Free Pascal Manual

__RESULT represents the function result return value.

__SELF represents the object method pointer in methods.

__OLDEBP represents the old base pointer in recusrive routines.

CALLING MECHANISM  Procedures and Functions are called with their parameters on the stack. Contrary to Turbo Pascal, all parameters are pushed on the stack, and they are pushed right to left, instead of left to right for Turbo Pascal. This is especially important if you have some assembly subroutines in Turbo Pascal which you would like to translate to Free Pascal. Function results are returned in the first register, if they fit in the register. For more information on this, see section (8.2) The registers are not saved when calling a function or procedure. If you want to call a procedure or function from assembly language, you must save any registers you wish to preserve. The first thing a procedure does is saving the base pointer, and setting the base (%ebp) pointer equal to the stack pointer (%esp). References to the pushed parameters and local variables are constructed using the base pointer. In practice this amounts to the following assembly code as the procedure or function header : pushl %ebp movl %esp,%ebpWhen the procedure or function exits, it clears the stack by means of the RET xx call, where xx is the total size of the pushed parameters on the stack. Thus, in case parameters with a total size of xx have been passed to a function, the generated exit sequence looks as follows: leave ret $xxWhen you want your code to be called by a C library or used in a C program, you will run into trouble because of this calling mechanism. In C, the calling procedure is expected to clear the stack, not the called procedure. To avoid this problem, Free Pascal supports the export modifier. Procedures that are defined using the export modifier, use a C-compatible calling mechanism. This means that they can be called from a C program or library, or that you can use them as a callback function. This also means that you cannot call this procedure or function from your own program, since your program uses the Pascal calling convention. However, in the exported function, you can of course call other Pascal routines. Technically, the C calling mechanism is implemented by generating the following exit sequence at the end of your function or procedure: leave {Copies EBP to ESP, pops EBP from the stack.} retComparing this exit sequence with the previous one makes it clear why you cannot call this procedure from within Pascal: The arguments still are on the stack when the procedure exits. As of version 0.9.8, the Free Pascal compiler supports also the cdecl and stdcall modifiers, as found in Delphi. The cdecl modifier does the same as the export modifier, and stdcall does nothing, since Free Pascal pushes the paramaters from right to left by default. All this is summarized in table (3.1). The first column lists the modifier you specify for a procedure declaration. The second one lists the order the paramaters are pushed on the stack. The third column specifies who is responsible for cleaning the stack: the caller or the called function. Finally, the last column specifies if registers are used to pass parameters to the function.   Table 3.1: Calling mechanisms in Free Pascal

Modifier Pushing order Stack cleaned by Parameters in registers (none) Right-to-left Function No cdecl Right-to-left Caller No

Page 66 Free Pascal Manual

Page 67: Free Pascal Manual

export Right-to-left Caller No stdcall Right-to-left Function No

More about this can be found in chapter (4) on linking.

TELLING THE COMPILER WHAT REGISTERS HAVE CHANGED  When the compiler uses variables, it sometimes stores them, or the result of some calculations, in the processor registers. If you insert assembler code in your program that modifies the processor registers, then this may interfere with the compiler's idea about the registers. To avoid this problem, Free Pascal allows you to tell the compiler which registers have changed. The compiler will then avoid using these registers. Telling the compiler which registers have changed, is done by specifying a set of register names behind an assembly block, as follows: asm ...end ['R1',...,'Rn'];Here R1 to Rn are the names of the (extended) registers you modify in your assembly code. They can be one of 'EAX', 'EBX', 'ECX', 'EDX', 'EDI', 'ESI' for the Intel processor. As an example : asm movl BP,%eax movl 4(%eax),%eax movl %eax,__RESULT end ['EAX'];This example tells the compiler that the EAX register was modified.

Free Pascal Manual Page 67

Page 68: Free Pascal Manual

LINKING ISSUES  When you only use Pascal code, and Pascal units, then you will not see much of the part that the linker plays in creating your executable. The linker is only called when you compile a program. When compiling units, the linker isn't invoked. However, there are times that you want to C libraries, or to external object files that are generated using a C compiler (or even another pascal compiler). The Free Pascal compiler can generate calls to a C function, and can generate functions that can be called from C (exported functions). However, these exported functions cannot be called from inside Pascal anymore. More on these calling conventions can be found in section (3.3). In general, there are 2 things you must do to use a function that resides in an external library or object file:

1. You must make a pascal declaration of the function or procedure you want to use.2. You must tell the compiler where the function resides, i.e. in what object file or what library,

so the compiler can link the necessary code in. The following sections attempt to explain how to do this.

Declaring an external function or procedure Explicitly linking an object file in your program Linking your program to a library Making a shared library

DECLARING AN EXTERNAL FUNCTION OR PROCEDURE  The first step in using external code blocks is declaring the function you want to use. Free Pascal supports Delphi syntax, i.e. you must use the external directive. There exist four variants of the external direcive :

1. A simple external declaration: Procedure ProcName (Args : TPRocArgs); external;The external directive tells the compiler that the function resides in an external block of code. You can use this together with the {$L } or {$LinkLib } directives to link to a function or procedure in a library or external object file.

2. You can give the external directive a library name as an argument: Procedure ProcName (Args : TPRocArgs); external 'Name';This tells the compiler that the procedure resides in a library with name 'Name'. This method is equivalent to the following: Procedure ProcName (Args : TPRocArgs);external;{$LinkLib 'Name'}

3. The external can also be used with two arguments: Procedure ProcName (Args : TPRocArgs); external 'Name' name 'OtherProcName';This has the same meaning as the previous declaration, only the compiler will use the name 'OtherProcName' when linking to the library. This can be used to give different names to procedures and functions in an external library. This method is equivalent to the following code: Procedure OtherProcName (Args : TProcArgs); external;{$LinkLib 'Name'}

Procedure ProcName (Args : TPRocArgs);

begin OtherProcName (Args);end;

4. Lastly, onder and OS/2, there is a fourth possibility to specify an external function: In .DLL

Page 68 Free Pascal Manual

Page 69: Free Pascal Manual

files, functionas also have a unique number (their index). It is possible to refer to these fuctions using their index: Procedure ProcName (Args : TPRocArgs); external 'Name' Index SomeIndex;This tells the compiler that the procedure ProcName resides in a dynamic link library, with index SomeIndex. Remark: Note that this is ONLY available under and OS/2.

In earlier versions of the Free Pascal compiler, the following construct was also possible : Procedure ProcName (Args : TPRocArgs); [ C ];This method is equivalent to the following statement: Procedure ProcName (Args : TPRocArgs); cdecl; external;However, the [ C ] directive is no longer supoerted as of version 0.99.5 of Free Pascal, therefore you should use the external directive, with the cdecl directive, if needed.

EXPLICITLY LINKING AN OBJECT FILE IN YOUR PROGRAM  Having declared the external function that resides in an object file, you can use it as if it was defined in your own program or unit. To produce an executable, you must still link the object file in. This can be done with the {$L 'file.o'} directive. This will cause the linker to link in the object file file.o. On LINUX systems, this filename is case sensitive. Under DOS, case isn't important. Note that file.o must be in the current directory if you don't specify a path. The linker will not search for file.o if it isn't found. You cannot specify libraries in this way, it is for object files only. Here we present an example. Consider that you have some assembly routine that calculates the nth Fibonacci number : .text

.align 4.globl Fibonacci

.type Fibonacci,@functionFibonacci:

pushl %ebpmovl %esp,%ebpmovl 8(%ebp),%edxxorl %ecx,%ecxxorl %eax,%eaxmovl $1,%ebxincl %edx

loop:decl %edxje endloopmovl %ecx,%eaxaddl %ebx,%eaxmovl %ebx,%ecxmovl %eax,%ebxjmp loop

endloop:movl %ebp,%esp

popl %ebpret

Then you can call this function with the following Pascal Program: Program FibonacciDemo;

var i : longint;

Function Fibonacci (L : longint):longint;cdecl;external;

Free Pascal Manual Page 69

Page 70: Free Pascal Manual

{$L fib.o}

begin For I:=1 to 40 do writeln ('Fib(',i,') : ',Fibonacci (i));end.With just two commands, this can be made into a program : as -o fib.o fib.spp fibo.ppThis example supposes that you have your assembler routine in fib.s, and your Pascal program in fibo.pp.

LINKING YOUR PROGRAM TO A LIBRARY  To link your program to a library, the procedure depends on how you declared the external procedure. If you used thediffers a little from the procedure when you link in an object file. although the declaration step remains the same (see 4.1 on how to do that). In case you used the follwing syntax to declare your procedure: Procedure ProcName (Args : TPRocArgs); external 'Name';You don't need to take additional steps to link your file in, the compiler will do all that is needed for you. In case you used Procedure ProcName (Args : TPRocArgs); external;You still need to explicity link to the library. This can be done in 2 ways:

1. You can tell the compiler in the source file what library to link to using the {$LinkLib 'Name'} directive: {$LinkLib 'gpm'}This will link to the gpm library. On LINUX systems, you needn't specify the extension or 'lib' prefix of the library. The compiler takes care of that. On DOS or systems, you need to specify the full name.

2. You can also tell the compiler on the command-line to link in a library: The -k option can be used for that. For example ppc386 -k'-lgpm' myprog.ppIs equivalent to the above method, and tells the linker to link to the gpm library.

As an example; consider the following program : program printlength;

{$linklib c} { Case sensitive }

{ Declaration for the standard C function strlen }Function strlen (P : pchar) : longint; cdecl;external;

begin Writeln (strlen('Programming is easy !'));end.This program can be compiled with : pp prlen.ppSupposing, of course, that the program source resides in prlen.pp. You cannot use procedures or functions that have a variable number of arguments in C. Pascal doesn't support this feature of C.

MAKING A SHARED LIBRARY 

Page 70 Free Pascal Manual

Page 71: Free Pascal Manual

Free Pascal supports making shared libraries in a straightforward and easy manner. If you want to make libraries for other Free Pascal programmers, you just need to provide a command line switch. If you want C programmers to be able to use your code as well, you will need to adapt your code a little. This process is described first.

Adapting your codeIf you want to make your procedures and functions available to C programmers, you can do this very easily. All you need to do is declare the functions and procedures that you want to make available as Export, as follows: Procedure ExportedProcedure ; export;This tells the compiler that it shouldn't clear the stack upon exiting the procedure (see section (3.3)), thus enabling a C program to call your function. It also means that your Pascal program can't call this function, since it will be using the C calling mechanism. Remark : You can only declare a function as exported in the Implementation section of a unit. This function may not appear in the interface part of a unit. This is logical, since a Pascal routine cannot call an exported function, anyway. However, the generated object file will not contain the name of the function as you declared it. The Free Pascal compiler ''mangles'' the name you give your function. It makes the name all-uppercase, and adds the types of all parameters to it. For Free Pascal units, this doesn't matter, since the .ppu unit file contains all information to map your function declaration onto the mangled name in the object file. For a C programmer, who has no access to the .ppu file, this is not very convenient. That is why Free Pascal has the Alias modifier. The Alias modifier allows you to specify another name (a nickname) for your function or procedure. The prototype for an aliased function or procedure is as follows : Procedure AliasedProc; [ Alias : 'AliasName'];The procedure AliasedProc will also be known as AliasName. Take care, the name you specify is case sensitive (as C is). Of course, you want to combine these two features of Free Pascal, to export a function under a reasonable name; If you want to do that, you must first specify that the function is to be exported, and then only declare an alias: Procedure ExportToCProc; Export; [Alias : 'procname'];After that, any C program will be able to use your procedure or function. Remark: If you use in your unit functions that are in other units, or system functions, then the C program will need to link in the object files from the units too.

Compiling librariesOnce you have your (adapted) code, with exported and other functions, you can compile your unit, and tell the compiler to make it into a library. The compiler will simply compile your unit, and perform the necessary steps to transform it into a static or shared (dynamical) library. You can do this as follows, for a dynamical library: ppc386 -Uld myunitOn LINUX this will leave you with a file libmyunit.so. On and OS/2, this will leave you with myunit.dll. If you want a static library, you can do ppc386 -Uls myunitThis will leave you with libmyunit.a and a file myunit.ppl. The myunit.ppl is the unit file needed by the Free Pascal compiler. The extension .ppl means that the file describes a unit that resides in a library. The resulting files are then libraries. To make static libraries, you need the ranlib or ar program on your system. It is standard on any LINUX system, and is provided with the GCC compiler under DOS. BEWARE: This command doesn't include anything but the current unit in thelibrary. Other units are left out, so if you use code from other units, you must dpley them together with your library.

Moving units into a libraryYou can put multiple units into a library with the ppumove command, as follows: ppumove unit1 unit2 unit3 nameThis will move 3 units in 1 library (called libname.so on linux, name.dll on ) and it will create 3 files unit1.ppl, unit2.ppl and file3.ppl, which are unit files, but which tell the compiler to look in library

Free Pascal Manual Page 71

Page 72: Free Pascal Manual

name when linking your executable. The ppumove program has options to create statical or dynammical libraries. It is provided with the compiler.

Unit searching strategyWhen you compile a program or unit, the compiler will by default always look for .ppl files. If it doesn't find one, it will look for a .ppu file. You can disable this behaviour by specifying the -Cs switch. This tells the compiler to make a static binary, and refrains it from looking for units which reside in a library. You can tell the compiler only to use dynamic libraries by specifying the -Cd switch; the compiler will then only look for .ppl files, and will give an error if it doesn't find one.

Page 72 Free Pascal Manual

Page 73: Free Pascal Manual

OBJECTS  In this short chapter we give some technical things about objects. For instructions on how to use and declare objects, see Reference guide.

Constructor and Destructor calls Memory storage of objects The Virtual Method Table

CONSTRUCTOR AND DESTRUCTOR CALLS  When using objects that need virtual methods, the compiler uses two help procedures that are in the run-time library. They are called Help_Destructor and Help_Constructor, and they are written in assebly language. They are used to allocate the necessary memory if needed, and to insert the Virtual Method Table (VMT) pointer in the newly allocated object. When the compiler encounters a call to an object's constructor, it sets up the stack frame for the call, and inserts a call to the Help_Constructor procedure before issuing the call to the real constuctor. The helper procedure allocates the needed memory (if needed) and inserts the VMT pointer in the object. After that, the real constructor is called. A call to Help_Destructor is inserted in every destructor declaration, just before the destructor's exit sequence.

MEMORY STORAGE OF OBJECTS  Objects are stored in memory just as ordinary records with an extra field : a pointer to the Virtual Method Table (VMT). This field is stored first, and all fields in the object are stored in the order they are declared. This field is initialized by the call to the object's Constructor method. If the object you defined has no virtual methods, then a nil is stored in the VMT pointer. This ensures that the size of objects is equal, whether they have virtual methods ore not. The memory allocated looks as in table (5.1).   Table 5.1: Object memory layout

Offset What +0 Pointer to VMT. +4 Data. All fields in the order the've been declared. ...

THE VIRTUAL METHOD TABLE  The Virtual Method Table (VMT) for each object type consists of 2 check fields (containing the size of the data), a pointer to the object's anchestor's VMT (Nil if there is no anchestor), and then the pointers to all virtual methods. The VMT layout is illustrated in table (5.2). The VMT is constructed by the compiler. Every instance of an object receives a pointer to its VMT.   Table 5.2: Virtual Method Table memory layout

Offset What +0 Size of object type data +4 Minus the size of object type data. Enables determining of valid VMT pointers.

+8 Pointer to ancestor VMT, Nil if no ancestor available.

+12 Pointers to the virtual methods. ...

Free Pascal Manual Page 73

Page 74: Free Pascal Manual

GENERATED CODE  The Free Pascal compiler relies on the assembler to make object files. It generates just the assembly language file. In the following two sections, we discuss what is generated when you compile a unit or a program.

Units Programs

UNITS  When you compile a unit, the Free Pascal compiler generates 2 files :

1. A unit description file (with extension .ppu).2. An assembly language file (with extension .s).

The assembly language file contains the actual source code for the statements in your unit, and the necessary memory allocations for any variables you use in your unit. This file is converted by the assembler to an object file (with extension .o) which can then be linked to other units and your program, to form an executable. By default (compiler version 0.9.4 and up), the assembly file is removed after it has been compiled. Only in the case of the -s command-line option, the assembly file must be left on disk, so the assembler can be called later. The unit file contains all the information the compiler needs to use the unit:

1. Other used units, both in interface and implementation.2. Types and variables from the interface section of the unit.3. Function declarations from the interface section of the unit.4. Some debugging information, when compiled with debugging.5. A date and time stamp.

Macros, symbols and compiler directives are not saved to the unit description file. Aliases for functions are also not written to this file, which is logical, since they cannot appear in the interface section of a unit. The detailed contents and structure of this file are described in the first appendix. You can examine a unit description file using the dumpppu program, which shows the contents of the file. If you want to distribute a unit without source code, you must provide both the unit description file and the object file. You can also provide a C header file to go with the object file. In that case, your unit can be used by someone who wishes to write his programs in C. However, you must make this header file yourself since the Free Pascal compiler doesn't make one for you.

PROGRAMS  When you compile a program, the compiler produces again 2 files :

1. An assembly language file containing the statements of your program, and memory allocations for all used variables.

2. A linker response file. This file contains a list of object files the linker must link together. The link response file is, by default, removed from the disk. Only when you specify the -s command-line option or when linking fails, then the ile is left on the disk. It is named link.res. The assembly language file is converted to an object file by the assembler, and then linked together with the rest of the units and a program header, to form your final program. The program header file is a small assembly program which provides the entry point for the program. This is where the execution of your program starts, so it depends on the operating system, because operating systems pass parameters to executables in wildly different ways. It's name is prt0.o, and the source file resides in prt0.s or some variant of this name. It usually resided where the system unit source for your system resides. It's main function is to save the environment and

Page 74 Free Pascal Manual

Page 75: Free Pascal Manual

command-line arguments, set up the stack. Then it calls the main program.

Free Pascal Manual Page 75

Page 76: Free Pascal Manual

MMX SUPPORT 

What is it about ? Saturation support Restrictions of MMX support Supported MMX operations Optimizing MMX support

WHAT IS IT ABOUT ?  Free Pascal supports the new MMX (Multi-Media extensions) instructions of Intel processors. The idea of MMX is to process multiple data with one instruction, for example the processor can add simultaneously 4 words. To implement this efficiently, the Pascal language needs to be extended. So Free Pascal allows to add for example two array[0..3] of word, if MMX support is switched on. The operation is done by the MMX unit and allows people without assembler knowledge to take advantage of the MMX extensions. Here is an example: uses MMX; { include some predefined data types }

const { tmmxword = array[0..3] of word;, declared by unit MMX } w1 : tmmxword = (111,123,432,4356); w2 : tmmxword = (4213,63456,756,4);

var w3 : tmmxword; l : longint;

begin if is_mmx_cpu then { is_mmx_cpu is exported from unit mmx } begin{$mmx+} { turn mmx on } w3:=w1+w2;{$mmx-} end else begin for i:=0 to 3 do w3[i]:=w1[i]+w2[i]; end;end.

SATURATION SUPPORT  One important point of MMX is the support of saturated operations. If a operation would cause an overflow, the value stays at the highest or lowest possible value for the data type: If you use byte values you get normally 250+12=6. This is very annoying when doing color manipulations or changing audio samples, when you have to do a word add and check if the value is greater than 255. The solution is saturation: 250+12 gives 255. Saturated operations are supported by the MMX unit. If you want to use

Page 76 Free Pascal Manual

Page 77: Free Pascal Manual

them, you have simple turn the switch saturation on: $saturation+ Here is an example: Program SaturationDemo;{ example for saturation, scales data (for example audio) with 1.5 with rounding to negative infinity}

var audio1 : tmmxword;

const helpdata1 : tmmxword = ($c000,$c000,$c000,$c000); helpdata2 : tmmxword = ($8000,$8000,$8000,$8000);

begin { audio1 contains four 16 bit audio samples }{$mmx+} { convert it to $8000 is defined as zero, multiply data with 0.75 } audio1:=tmmxfixed16(audio1+helpdata2)*tmmxfixed(helpdata1);{$saturation+} { avoid overflows (all values>$7fff becomes $ffff) } audio1:=(audio1+helpdata2)-helpdata2;{$saturation-} { now mupltily with 2 and change to integer } audio1:=(audio1 shl 1)-helpdata2;{$mmx-}end.

RESTRICTIONS OF MMX SUPPORT  In the beginning of 1997 the MMX instructions were introduced in the Pentium processors, so multitasking systems wouldn't save the newly introduced MMX registers. To work around that problem, Intel mapped the MMX registers to the FPU register. The consequence is that you can't mix MMX and floating point operations. After using MMX operations and before using floating point operations, you have to call the routine EMMS of the MMX unit. This routine restores the FPU registers. careful: The compiler doesn't warn, if you mix floating point and MMX operations, so be careful. The MMX instructions are optimized for multi media (what else?). So it isn't possible to perform each operation, some opertions give a type mismatch, see section 7.4 for the supported MMX operations An important restriction is that MMX operations aren't range or overflow checked, even when you turn range and overflow checking on. This is due to the nature of MMX operations. The MMX unit must be always used when doing MMX operations because the exit code of this unit clears the MMX unit. If it wouldn't do that, other program will crash. A consequence of this is that you can't use MMX operations in the exit code of your units or programs, since they would interfere with the exit code of the MMX unit. The compiler can't check this, so you are responsible for this !

OPTIMIZING MMX SUPPORT  Here are some helpful hints to get optimal performance:

The EMMS call takes a lot of time, so try to seperate floating point and MMX operations. Use MMX only in low level routines because the compiler saves all used MMX registers

Free Pascal Manual Page 77

Page 78: Free Pascal Manual

when calling a subroutine. The NOT-operator isn't supported natively by MMX, so the compiler has to generate a

workaround and this operation is inefficient. Simple assignements of floating point numbers don't access floating point registers, so you

need no call to the EMMS procedure. Only when doing arithmetic, you need to call the EMMS procedure.

Page 78 Free Pascal Manual

Page 79: Free Pascal Manual

MEMORY ISSUES 

The 32-bit model. The stack Accessing DOS memory under the Go32 extender

THE 32-BIT MODEL.  The Free Pascal Pascal compiler issues 32-bit code. This has several consequences:

You need a i386 or higher processor to run the generated code. The compiler functions on a 286 when you compile it using Turbo Pascal, but the generated programs cannot be assembled or executed.

You don't need to bother with segment selectors. Memory can be addressed using a single 32-bit pointer. The amount of memory is limited only by the available amount of (virtual) memory on your machine.

The structures you define are unlimited in size. Arrays can be as long as you want. You can request memory blocks from any size.

The fact that 32-bit code is used, means that some of the older Turbo Pascal constructs and functions are obsolete. The following is a list of functions which shouldn't be used anymore: Seg()

: Returned the segment of a memory address. Since segments have no more meaning, zero is returned in the Free Pascal run-time library implementation of Seg.

Ofs() : Returned the offset of a memory address. Since segments have no more meaning, the complete address is returned in the Free Pascal implementation of this function. This has as a consequence that the return type is Longint instead of Word.

Cseg(), Dseg() : Returned, respectively, the code and data segments of your program. This returns zero in the Free Pascal implementation of the system unit, since both code and data are in the same memory space.

Ptr accepted a segment and offset from an address, and would return a pointer to this address. This has been changed in the run-time library. Standard it returns now simply the offset. If you want to retain the old functionality, you can recompile the run-time library with the DoMapping symbol defined. This will restore the Turbo Pascal behaviour.

memw and mem these arrays gave access to the DOS memory. Free Pascal supports them, they are mapped into DOS memory space. You need the GO32 unit for this.

You shouldn't use these functions, since they are very non-portable, they're specific to DOS and the ix86 processor. The Free Pascal compiler is designed to be portable to other platforms, so you should keep your code as portable as possible, and not system specific. That is, unless you're writing some driver units, of course.

THE STACK  The stack is used to pass parameters to procedures or functions, to store local variables, and, in some cases, to return function results. When a function or procedure is called, then the following is done by the compiler :

1. If there are any parameters to be passed to the procedure, they are pushed from right to left on the stack.

2. If a function is called that returns a variable of type String, Set, Record, Object or Array, then an address to store the function result in, is pushed on the stack.

3. If the called procedure or function is an object method, then the pointer to self is pushed on

Free Pascal Manual Page 79

Page 80: Free Pascal Manual

the stack.4. If the procedure or function is nested in another function or procedure, then the frame pointer

of the parent procedure is pushed on the stack.5. The return address is pushed on the stack (by the Call instruction).

The resulting stack frame upon entering looks as in table (8.1).   Table 8.1: Stack frame when calling a procedure

Offset What is stored Optional ? +x parameters Yes +12 function result Yes +8 self Yes +4 Frame pointer of parent procedure Yes +0 Return address No

The stack is cleared with the ret I386 instruction, meaning that the size of all pushed parameters is limited to 64K. The stack size is unlimited for all supported platforms. On the GO32V2 platform, the minimum guaranteed stack is 128Kb, but this can be set with the -Ctxxx compiler switch. The heap is used to store all dynamic variables, and to store class instances. The interface to the heap is the same as in Turbo Pascal, although the effects are maybe not the same. On top of that, the Free Pascal run-time library has some extra possibilities, not available in Turbo Pascal. These extra possibilities are explained in the next subsections.

The heap growsFree Pascal supports the HeapEerror procedural variable. If this variable is non-nil, then it is called in case you try to allocate memory, and the heap is full. By default, HeapError points to the GrowHeap function, which tries to increase the heap. The growheap function issues a system call to try to increase the size of the memory available to your program. It first tries to increase memory in a 1 Mb. chunk. If this fails, it tries to increase the heap by the amount you requested from the heap. If the call to GrowHeap has failed, then a run-time error is generated, or nil is returned, depending on the GrowHeap result. If the call to GrowHeap was successful, then the needed memory will be allocated.

Using BlocksIf you need to allocate a lot of small block for a small period, then you may want to recompile the run-time library with the USEBLOCKS symbol defined. If it is recompiled, then the heap management is done in a different way. The run-time library keeps a linked list of allocated blocks with size up to 256 bytes. By default, it keeps 32 of these lists. When a piece of memory in a block is deallocated, the heap manager doesn't really deallocate the occupied memory. The block is simply put in the linked list corresponding to its size. When you then again request a block of memory, the manager checks in the list if there is a non-allocated block which fits the size you need (rounded to 8 bytes). If so, the block is used to allocate the memory you requested. This method of allocating works faster if the heap is very fragmented, and you allocate a lot of small memory chunks. Since it is invisible to the program, this provides an easy way of improving the performance of the heap manager.

Using the split heapRemark : The split heap is still somewhat buggy. Use at your own risk for the moment. The split heap can be used to quickly release a lot of blocks you alloated previously. Suppose that in a part of your program, you allocate a lot of memory chunks on the heap. Suppose that you know that you'll release all this memory when this particular part of you program is finished. In Turbo Pascal, you could foresee this, and mark the position of the heap (using the Mark function)

Page 80 Free Pascal Manual

Page 81: Free Pascal Manual

when entering this particular part of your program, and release the occupied memory in one call with the Release call. For most purposes, this works very good. But sometimes, you may need to allocate something on the heap that you don't want deallocated when you release the allocated memory. That is where the split heap comes in. When you split the heap, the heap manager keeps 2 heaps: the base heap (the normal heap), and the temporary heap. After the call to split the heap, memory is allocated from the temporary heap. When you're finished using all this memory, you unsplit the heap. This clears all the memory on the split heap with one call. After that, memory will be allocated from the base heap again. So far, nothing special, nothing that can't be done with calls to mark and release. Suppose now that you have split the heap, and that you've come to a point where you need to allocate memory that is to stay allocated after you unsplit the heap again. At this point, mark and release are of no use. But when using the split heap, you can tell the heap manager to -temporarily- use the base heap again to allocate memory. When you've allocated the needed memory, you can tell the heap manager that it should start using the temporary heap again. When you're finished using the temporary heap, you release it, and the memory you allocated on the base heap will still be allocated. To use the split-heap, you must recompile the run-time library with the TempHeap symbol defined. This means that the following functions are available : procedure Split_Heap; procedure Switch_To_Base_Heap; procedure Switch_To_Temp_Heap; procedure Switch_Heap; procedure ReleaseTempHeap; procedure GetempMem(var p : pointer;size : longint);split_heap is used to split the heap. It cannot be called two times in a row, without a call to releasetempheap. Releasetempheap completely releases the memory used by the temporary heap. Switching temporarily back to the base heap can be done using the switch_to_base_heap call, and returning to the temporary heap is done using the switch_to_temp_heap call. Switching from one to the other without knowing on which one your are right now, can be done using the switch_heap call, which will split the heap first if needed. A call to GetTempMem will allocate a memory block on the temporary heap, whatever the current heap is. The current heap after this call will be the temporary heap. Typically, what will appear in your code is the following sequence : Split_Heap...{ Memory allocation }...{ !! non-volatile memory needed !!}Switch_To_Base_Heap;getmem (P,size);Switch_To_Temp_Heap;...{Memory allocation}...ReleaseTempHeap;{All allocated memory is now freed, except for the memory pointed to by 'P' }...

ACCESSING DOS MEMORY UNDER THE GO32 EXTENDER  Because Free Pascal is a 32 bit compiler, and uses a DOS extender, accessing DOS memory isn't trivial. What follows is an attempt to an explanation of how to access and use DOS or real mode memory. In Proteced Mode, memory is accessed through Selectors and Offsets. You can think of Selectors as the

Free Pascal Manual Page 81

Page 82: Free Pascal Manual

protected mode equivalents of segments. In Free Pascal, a pointer is an offset into the DS selector, which points to the Data of your program. To access the (real mode) DOS memory, somehow you need a selector that points to the DOS memory. The GO32 unit provides you with such a selector: The DosMemSelector variable, as it is conveniently called. You can also allocate memory in DOS's memory space, using the global_dos_alloc function of the GO32 unit. This function will allocate memory in a place where DOS sees it. As an example, here is a function that returns memory in real mode DOS and returns a selector:offset pair for it. procedure dosalloc(var selector : word; var segment : word; size : longint);

var result : longint;

begin result := global_dos_alloc(size); selector := word(result); segment := word(result shr 16);end;(you need to free this memory using the global_dos_free function.) You can access any place in memory using a selector. You can get a selector using the allocate_ldt_descriptor function, and then let this selector point to the physical memory you want using the set_segment_base_address function, and set its length using set_segment_limit function. You can manipulate the memory pointed to by the selector using the functions of the GO32 unit. For instance with the seg_fillchar function. After using the selector, you must free it again using the free_ldt_selector function. More information on all this can be found in the Unit reference the chapter on the GO32 unit.

ANATOMY OF A UNIT FILE  A unit file consists of basically five parts:

1. A unit header.2. A file references part. This contains the references to used units and sources with name,

checksum and time stamps.3. A definition part. Contains all type and procedure definitions.4. A Symbol part. Contains all symbol names and references to their definitions.5. A list of units that are in the implementation part.

The header consists of a sequence of 20 bytes, together they give some information about the unit file, the compiler version that was used to generate the unit file, etc. The complete layout can be found in table (A.1). The header is generated by the compiler, and changes only when the compiler changes. The current and up-to-date header definition can be found in the files.pas source file of the compiler. Look in this file for the unitheader constant declaration.   Table A.1: Unit header structure.

Byte What is stored 0..3 The letters 'PPU' in upper case. This acts as a check. 4..6 The unit format as a 3 letter sequence : e.g. '0','1,'2' for format 12. 7,8 The compiler version and release numbers as bytes. 9 The target OS number. 10 Unit flags.11..14 Checksum (as a longint). 15,16 unused (equal to 255).

Page 82 Free Pascal Manual

Page 83: Free Pascal Manual

17..20 Marks start of unit file. After the header, in the second part, first the list of all source files for the unit is written. Each name is written as a direct copy of the string in memory, i.e. a length bytes, and then all characters of the string. This list includes any file that was included in the unit source with the {$i file} directive. The list is terminated with a $ff byte marker. After this, the list of units in the uses clause is written, together with their checksums. The file is written as a string, the checksum as a longint (i.e. four bytes). Again this list is terminated with a $ff byte marker. After that, in the third part, the definitions of all types, variables, constants, procedures and functions are written to the unit file. They are written in the following manner: First a byte is written, which determines the kind of definition that follows. then follows, as a series of bytes, a type-dependent description of the definition. The exact byte order for each type can be found in table (A.2)   

hline Type Start byte Size Stored fields Pointer 3 4 Reference to the type pointer points to.

Base type 2 9

Table A.2: Description of definition fields1 byte to indicate base type. 4-byte start range 4-byte end range

Array type 5 16

4-byte reference to element type. 4-byte reference to range type.4-byte start range (longint) 4-byte end range (longint)

Procedure 6 ?

4-byte reference to the return type definition. 2 byte Word containing modifiers. 2 byte Word containing number of parameters. 5 bytes per parameter.1 byte : used registers. String containing the mangled name. 8 bytes.

Procedural type 21 ?

4-byte reference to the return type definition. 2 byte Word containing modifiers. 2 byte Word containing number of parameters. 5 bytes per parameter.

String 9 1 1 byte containing the length of the string.

Record 15 variable

Longint indicating record length list of fields, to be read as unit in itself. $ff end marker.

Class 18 variable

Longint indicating data length String with mangled name of class.4 byte reference to ancestor class.list of fields, to be read as unit in itself. $ff end marker.

file 16 1(+4) 1 byte for type of file. 4-byte reference to type of typed file.

Enumeration 19 4 Biggest element. set 20 5 4-byte reference to set element type.

Free Pascal Manual Page 83

Page 84: Free Pascal Manual

1 byte flag.

This list of definitions is again terminated with a $ff byte marker. After that, a list of symbols is given, together with a reference to a definition. This represents the names of the declarations, and the definition they refer to. A reference consists of 2 words : the first word indicates the unit number (as it appears in the uses clause), and the second word is the number of the definition in that unit. A nil reference is stored as $ffffffff. After this follows again a $ff byte terminated list of filenames: The names of the units in the uses clause of the implementation section.

LIST OF COMPILER SOURCE FILES  What follows is a list of all compiler files, with a short description of what they contain. If you're looking for something in the compiler, this list may give you a hint on where to find it. The first list is a list of processor dependent files. aasm.pas

This unit defines some abstract assembler objects and routines. It is used by the processor-specific assembly routines.

alpha.pas, i386.pas, m68k.pas These units describe a processor, its registers, flags etc. The basis for every generated instruction. Currently the DEC alpha, Intel 386 or higher and Motorola 68000 processors are supported.

tgen68k.pas, tgeni386.pas These units export help functions for the code generator, which are processor specific, they form a buffer between the code generator and the machine-specific stuff.

cg68k.pas, cgi386.pas, cgi3862.pas These units contain the code generators for the different processor types. For the I386 there are 2 files.

cga68k.pas cgai386.pas These units contain frequently-used helper functions for the processor-specific code generators.

aopt386.pas These units contain the code optimizers for the different processor-types.

asmalpha.pas This unit defines some DEC alpha assembly constructs.

attasmi3.pas, gasasm6.pas, intasmi3.pas These units define processor-specific assembly output classes.

opts386.pas, opts68k.pas These units process command-line options that are processor specific.

radi386.pas rai386.pas ratti386.pas These units process inline assembly in different styles (AT&T style, Intel style, and direct style) for the Intel 386 processor.

rasm386.pas This unit provides some helper routines for the assembly readers.

The second list is a list with processor-independent files. catch.pas

This is a LINUX specific call. It intercepts a segmentation fault, and lets the compiler exit gracefully.

cobjects.pas This unit provides some basic objects for the compiler: buffered files, linked lists, string containers, etc.

compiler.pas This unit contains the actual compile function.

errors.pas This unit takes care of error-handling: displaying of error messages, reading of error-definitions

Page 84 Free Pascal Manual

Page 85: Free Pascal Manual

etc. files.pas

This unit contains file management routines, such as finding of files etc. It is highly OS dependent. gdb.pas

This unit implements the debugging information generation for the gnu GDB debugger. globals.pas

This unit defines some help routines that are used throughout the entire compiler, and it does some initializations.

hcodegen.pas This unit contains processor-independent helper routines for the code generator.

options.pas This unit processes the processor-independent command-line options.

scanner.pas This unit contains the scanner routines. Here the input file is read and split in tokens.

parser.pas, pass_1.pas These units contain the actual Pascal parser.

pp.pas This is the main program. It does some initializations and sets the ball rolling.

symtable.pas This unit contains the code that keeps the symbol tables for the parser. It also contains the code to read a unit file.

systems.pas This unit defines the different operating systems: names, specifications of file systems, places where to look for things etc.

sysutils.pas This unit keeps routines for exception handling.

tree.pas The main structure for the code generator is a tree of operators and operands, and this unit defines the tree structure.

types.pas This unit contains some helper routines for handling of different Pascal types.

verbose.pas This unit provides the verbosity support. All messages from the compiler are put on screen with this unit.

COMPILER LIMITS  Although many of the restrictions imposed by the MS-DOS system are removed by use of an extender, or use of another operating system, there still are some limitations to the compiler:

1. String constants are limited to 128 characters. All other characters are simply dropped from the definition.

2. The length of generated unit files is limited to 65K for the real-mode compiler, and to 1Mb for the 32-bit compiler. This limit can be changed by changing the bytearray1 type in cobjects.pas

3. Procedure or Function definitions can be nested to a level of 32.4. Maximally 255 units can be used in a program when using the real-mode compiler. When

using the 32-bit compiler, the limit is set to 1024. You can change this by redefining the maxunits constant in the files.pas compiler source file.

5. Procedures or functions accept parameters with a total size up to $ffff bytes. This limit is due to the RET instruction of the I386 processor. If the calls were made using the C convention this limit would disappear.

Free Pascal Manual Page 85

Page 86: Free Pascal Manual

OPTIMIZING TECHNIQUES USED IN THE COMPILER.Here follows a listing of the opimizing techniques used in the compiler:

1. When optimizing for a specific Processor (-O3, -O4, -O5 -O6, the following is done: In case statements, a check is done whether a jump table or a sequence of

conditional jumps should be used for optimal performance. Determines a number of strategies when doing peephole optimization: movzbl

(%ebp), %eax on PentiumPro and PII systems will be changed into xorl %eax,%eax; movb (%ebp),%al for lesser systems.

Cyrix 6x86 processor owners should optimize with -O4 instead of -O5, because -O5 leads to larger code, and thus to smaller speed, according to the Cyrix developers FAQ.

2. When optimizing for speed (-OG) or size (-Og), a choice is made between using shorter instructions (for size) such as enter $4, or longer instructions subl $4,%esp for speed. When smaller size is requested, things aren't aligned on 4-byte boundaries. When speed is requested, things are aligned on 4-byte boundaries as much as possible.

3. Simple optimization (-Oa) makes sure the peephole optimizer is used, as well as the reloading optimizer.

4. Maximum optimization (-Ox) avoids creation of stack frames if they aren't required, and unnecessary loading of registers is avoided as much as possible. (buggy at the moment (version 0.99.0).

5. Uncertain optimizations (-Oz): With this switch, the reloading optimizer (enabled with -Oa) can be forced into making uncertain optimizations. You can enable uncertain optimizations only in certain cases, otherwise you will produce a bug; the following technical description tells you when to use them:

If uncertain optimizations are enabled, the reloading optimizer assumes that

If something is written to a local/global register or a procedure/function parameter, this value doesn't overwrite the value to which a pointer points.

If something is written to memory pointed to by a pointer variable, this value doesn't overwrite the value of a local/global variable or a procedure/function parameter.

The practical upshot of this is that you cannot use the uncertain optimizations if you access any local or global variables through pointers. In theory, this includes Var parameters, but it is all right if you don't both read the variable once through its Var reference and then read it using it's name. The following example will produce bad code when you switch on uncertain optimizations: Var temp: Longint;

Procedure Foo(Var Bar: Longint);Begin If (Bar = temp) Then Begin Inc(Bar); If (Bar <> temp) then Writeln('bug!') EndEnd;

Begin Foo(Temp);End.The reason it produces bad code is because you access the global variable Temp both through its name Temp and through a pointer, in this case using the Bar variable

Page 86 Free Pascal Manual

Page 87: Free Pascal Manual

parameter, which is nothing but a pointer to Temp in the above code. On the other hand, you can use the uncertain optimizations if you access global/local variables or parameters through pointers, and only access them through this pointer. For example: Type TMyRec = Record a, b: Longint; End; PMyRec = ^TMyRec;

TMyRecArray = Array [1..100000] of TMyRec; PMyRecArray = ^TMyRecArray;

Var MyRecArrayPtr: PMyRecArray; MyRecPtr: PMyRec; Counter: Longint;

Begin New(MyRecArrayPtr); For Counter := 1 to 100000 Do Begin MyRecPtr := @MyRecArrayPtr^[Counter]; MyRecPtr^.a := Counter; MyRecPtr^.b := Counter div 2; End;End.Will produce correct code, because the global variable MyRecArrayPtr is not accessed directly, but through a pointer (MyRecPtr in this case). In conclusion, one could say that you can use uncertain optimizations only when you know what you're doing.

Free Pascal Manual Page 87

Page 88: Free Pascal Manual

Reference guide for the system unit, and supported Pascal constructs.

Page 88 Free Pascal Manual

Page 89: Free Pascal Manual

Free Pascal Manual Page 89

Page 90: Free Pascal Manual

Contents List of Tables Supported Pascal language constructs

Data types Integer types Real types Character types

Char Strings PChar

Booleans Arrays Pointers Procedural types Records Set types Enumeration types

Constants Ordinary constants Typed constants

Objects The Turbo Pascal approach The Delphi approach

Statements controlling program flow. Assignments The Case statement The For..to/downto..do statement The Goto statement The If..then..else statement The Repeat..until statement The While..do statement The With statement Compound statements

Using functions and procedures Function overloading Const parameters Open array parameters

Using assembler in your code Modifiers

Public cdecl external Export StdCall Alias [RegisterList] Unsupported Turbo Pascal modifiers

Reference : The system unit Types, Constants and Variables

Types Constants Variables

Functions and Procedures Abs

Page 90 Free Pascal Manual

Page 91: Free Pascal Manual

Addr Append Arctan Assign Blockread Blockwrite Chdir Chr Close Concat Copy Cos CSeg Dec Delete Dispose DSeg Eof Eoln Erase Exit Exp Filepos Filesize Fillchar Fillword Flush Frac Freemem Getdir Getmem Halt Hi Inc Insert Int IOresult Length Ln Lo Lowercase Mark Maxavail Memavail Mkdir Move New Odd Ofs Ord Paramcount Paramstr Pi Pos Ptr

Free Pascal Manual Page 91

Page 92: Free Pascal Manual

Random Randomize Read Readln Release Rename Reset Rewrite Rmdir Round Runerror Seek SeekEof SeekEoln Seg SetTextBuf Sin SizeOf Sptr Sqr Sqrt SSeg Str Swap Trunc Truncate Upcase Val Write Writeln

Index

Page 92 Free Pascal Manual

Page 93: Free Pascal Manual

List of Tables Predefined integer types Supported Real types PChar pointer arithmetic Set Manipulation operators Allowed C constructs in Free Pascal Unsupported modifiers

ABOUT THIS GUIDEThis document describes all constants, types, variables, functions and procedures as they are declared in the system unit. Furthermore, it describes all pascal constructs supported by Free Pascal, and lists all supported data types. It does not, however, give a detailed explanation of the pascal language. The aim is to list which Pascal constructs are supported, and to show where the Free Pascal implementation differs from the Turbo Pascal implementation. Throughout this document, we will refer to functions, types and variables with typewriter font. Functions and procedures gave their own subsections, and for each function or procedure we have the following topics:

Declaration

The exact declaration of the function.

Description

What does the procedure exactly do ?

Errors

What errors can occur.

See Also

Cross references to other related functions/commands.

The cross-references come in two flavours: References to other functions in this manual. In the printed copy, a number will appear after

this reference. It refers to the page where this function is explained. In the on-line help pages, this is a hyperlink, on which you can click to jump to the declaration.

References to Unix manual pages. (For linux related things only) they are printed in typewriter font, and the number after it is the Unix manual section.

Free Pascal Manual Page 93

Page 94: Free Pascal Manual

SUPPORTED PASCAL LANGUAGE CONSTRUCTS

In this chapter we describe the pascal constructs supported by Free Pascal, as well as the supported data types. This is not intended as an introduction to the Pascal language, although all language constructs will be covered. The main goal is to explain what is supported by Free Pascal, and where the Free implementation differs from the Turbo Pascal one.

Data types Integer types Real types Character types Booleans Arrays Pointers Procedural types Records Set types Enumeration types

Constants Ordinary constants Typed constants

Objects The Turbo Pascal approach The Delphi approach

Statements controlling program flow. Assignments The Case statement The For..to/downto..do statement The Goto statement The If..then..else statement The Repeat..until statement The While..do statement The With statement Compound statements

Using functions and procedures Function overloading Const parameters Open array parameters

Using assembler in your code Modifiers

Public cdecl external Export StdCall Alias [RegisterList] Unsupported Turbo Pascal modifiers

Page 94 Free Pascal Manual

Page 95: Free Pascal Manual

DATA TYPESFree Pascal supports the same data types as Turbo Pascal, with some extensions from Delphi.

Integer types Real types Character types Booleans Arrays Pointers Procedural types Records Set types Enumeration types

Integer typesThe integer types predefined in Free Pascal are listed in table (1.1).   Table 1.1: Predefined integer types

Type Range Size in bytes Byte 0 .. 255 1Shortint -127 .. 127 1Integer -32768 .. 32767 2Word 0 .. 65535 2Longint -2147483648 .. 2147483648 4Cardinal 0..4294967296 4

Free Pascal does automatic type conversion in expressions where different kinds of integer types are used. Free Pascal supports hexadecimal format the same way as Turbo Pascal does. To specify a constant value in hexadecimal format, prepend it with a dollar sign ($). Thus, the hexadecimal $FF equals 255 decimal. In addition to the support for hexadecimal notation, Free Pascal also supports binary notation. You can specify a binary number by preceding it with a percent sign (%). Thus, 255 can be specified in binary notation as %11111111.

Real typesFree Pascal uses the math coprocessor (or an emulation) for al its floating-point calculations. The native type for the coprocessor is Double. Other than that, all Turbo Pascal real types are supported. They're listed in table (1.2).   Table 1.2: Supported Real types

Type Range Significant digits Size Real 2.9E-39 .. 1.7E38 11-12 6Single 1.5E-45 .. 3.4E38 7-8 4Double 5.0E-324 .. 1.7E308 15-16 8Extended 1.9E-4951 .. 1.1E4932 19-20 10

Until version 0.9.1 of the compiler, all the real types are mapped to type Double, meaning that they all have size 8. From version 0.9.3, the Extended and single types are defined with the same suze as in

Free Pascal Manual Page 95

Page 96: Free Pascal Manual

Turbo Pascal. The SizeOf function is your friend here.

Character typesCHARFree Pascal supports the type Char. A Char is exactly 1 byte in size, and contains one character. You can specify a character constant by enclosing the character in single quotes, as follows : 'a' or 'A' are both character constants. You can also specify a character by their ASCII value, by preceding the ASCII value with the number symbol (#). For example specifying #65 would be the same as 'A'. Also, the caret character (^) can be used in combination with a letter to specify a character with ASCII

value less than 27. Thus ^G equals #7 (G is the seventh letter in the alphabet.) If you want to represent the single quote character, type it two times successively, thus '''' represents the single quote character.

STRINGSFree Pascal supports the String type as it is defined in Turbo Pascal. To declare a variable as a string, use the following declaration: Var S : String[Size];This will declare S as a variable of type String, with maximum length Size. Size can be any value from 1 to 255. Free Pascal reserves Size+1 bytes for the string S, and in the zeroeth element of the string (S[0]) it will store the length of the variable. If you don't specify the size of the string, 255 is taken as a default. To specify a constant string, you enclose the string in single-quotes, just as a Char type, only now you can have more than one character. Given that S is of type String, the following are valid assignments: S:='This is a string.';S:='One'+', Two'+', Three';S:='This isn''t difficult !';S:='This is a weird character : '#145' !';As you can see, the single quote character is represented by 2 single-quote characters next to each other. Strange characters can be specified by their ASCII value. The example shows also that you can add two strings. The resulting string is just the concatenation of the first with the second string, without spaces in between them. Strings can not be substracted, however.

PCHARFree Pascal supports the Delphi implementation of the PChar type. PChar is defined as a pointer to a Char type, but allows additional operations. The PChar type can be understood best as the Pascal equivalent of a C-style null-terminated string, i.e. a variable of type PChar is a pointer that points to an array of type Char, which is ended by a null-character (#0). Free Pascal supports initializing of PChar typed constants, or a direct assignment. For example, the following pieces of code are equivalent: program one;

var p : pchar;

begin P:='This is a null-terminated string.'; writeln (P);end.Results in the same as

Page 96 Free Pascal Manual

Page 97: Free Pascal Manual

program two;

const P : PChar = 'This is a null-terminated string.'

begin Writeln (P);end.These examples also show that it is possible to write the contents of the string to a file of type Text. The strings_ unit contains procedures and functions that manipulate the PChar type as you can do it in C. Since it is equivalent to a pointer to a type Char variable, it is also possible to do the following: Program three;

Var S : String[30]; P : Pchar;

begin S:='This is a null-terminated string.'#0; P:=@S[1]; writeln (P);end.This will have the same result as the previous two examples. You cannot add null-terminated strings as you can do with normal Pascal strings. If you want to concatenate two PChar strings, you will need to use the strings unit. However, it is possible to do some pointer arithmetic. You can use the operators + and - to do operations on PChar pointers. In table (1.3), P and Q are of type PChar, and I is of type Longint.   Table 1.3: PChar pointer arithmetic

Operation Result P + I Adds I to the address pointed to by P. I + P Adds I to the address pointed to by P. P - I Substracts I from the address pointed to by P. P - Q Returns, as an integer, the distance between 2 addresses

(or the number of characters between P and Q)

BooleansFree Pascal supports the Boolean type, with its two pre-defined possible values True and False. These are the only two values that can be assigned to a Boolean type. Of course, any expression that resolves to a boolean value, can also be assigned to a boolean type. Assuming B to be of type Boolean, the following are valid assignments: B:=True; B:=False; B:=1<>2; { Results in B:=True }Boolean expressions are also used in conditions. Remark: In Free Pascal, boolean expressions are always evaluated in such a way that when the result is known, the rest of the expression will no longer be evaluated (Called short-cut evaluation). In the following example, the function Func will never be called, which may have strange side-effects. ... B:=False; A := B and Func;Here Func is a function which returns a Boolean type.

Free Pascal Manual Page 97

Page 98: Free Pascal Manual

ArraysFree Pascal supports arrays as in Turbo Pascal, except that packed arrays are not supported. Multi-dimensional arrays are also supported.

PointersFree Pascal supports the use of pointers. A variable of the type Pointer contains an address in memory, where the data of another variable may be stored. Pointers can be typed, which means that they point to a particular kind of data. The type of this data is known at compile time. Consider the following example: Program pointers;

type Buffer = String[255]; BufPtr = ^Buffer;

Var B : Buffer; BP : BufPtr; PP : Pointer;

etc..In this example, BP is a pointer to a Buffer type; while B is a variable of type Buffer. B takes 256 bytes memory, and BP only takes 4 bytes of memory (enough to keep an adress in memory). Remark: Free Pascal treats pointers much the same way as C does. This means that you can treat a pointer to some type as being an array of this type. The pointer then points to the zeroeth element of this array. Thus the following pointer declaration Var p : ^Longint;Can be considered equivalent to the following array declaration: Var p : array[0..Infinity] of Longint;The reference P^ is then the same as p[0]. The following program illustrates this maybe more clear: program PointerArray;

var i : longint; p : ^longint; pp : array[0..100] of longint;

begin for i:=0 to 100 do pp[i]:=i; { Fill array } p:=@pp[0]; { Let p point to pp } for i:=0 to 100 do if p[i]<>pp[i] then writeln ('Ohoh, problem !')end.Free Pascal doesn't support pointer arithmetic as C does, however.

Procedural typesFree Pascal has support for procedural types, although it differs from the Turbo Pascal implementation of them. The type declaration remains the same. The two following examples are valid type declarations: Type TOneArg = Procedure (Var X : integer); TNoArg = Function : Real;

var proc : TOneArg;

Page 98 Free Pascal Manual

Page 99: Free Pascal Manual

func : TNoArg;Given these declarations, the following assignments are valid: Procedure printit (Var X : Integer);

begin writeln (x);end;...

P:=@printit;Func:=@Pi;From this example, the difference with Turbo Pascal is clear: In Turbo Pascal it isn't necessary to use the address operator (@) when assigning a procedural type variable, whereas in Free Pascal it is required.

RecordsFree Pascal supports records. The prototype type definition of a record is: Type RecType = Record Element1 : type1; Element2,Element3 : type2; ... Elementn ; Typen; end;Variant records are also supported: Type RecType = Record Element1 : type1; Case [PivotElmt:] Type Identifier of Value1 : (VarElt1, Varelt2 : Vartype1); Value2 : (VarElt3, Varelt4 : Vartype2); end;The variant part must be last in the record. The optional PivotElmt can be used to see which variant is active at a certain time. Remark: If you want to read a typed file with records, produced by a Turbo Pascal program, then chances are that you will not succeed in reading that file correctly. The reason for this is that by default, elements of a record are aligned at 2-byte boundaries, for performance reasons. This default behaviour can be changed with the {$PackRecords n} switch. Possible values for n are 1, 2 and 4. This switch tells the compiler to align elements of a record on 1,2 or 4 byte boundaries. Take a look at the following program: Program PackRecordsDemo;

type {$PackRecords 2} Trec1 = Record A : byte; B : Word; end; {$PACKRECORDS 1} Trec2 = Record A : Byte; B : Word; end;

Free Pascal Manual Page 99

Page 100: Free Pascal Manual

begin Writeln ('Size Trec1 : ',SizeOf(Trec1)); Writeln ('Size Trec2 : ',SizeOf(Trec2));end.The output of this program will be : Size Trec1 : 4Size Trec2 : 3And this is as expected. In Trec1, each of the elements A and B takes 2 bytes of memory, and in Trec1, A takes only 1 byte of memory. As from version 0.9.3 (a developers' version), Free Pascal supports also the 'packed record', this is a record where all the elements are byte-aligned. Thus the two following declarations are equivalent: {$PACKRECORDS 1} Trec2 = Record A : Byte; B : Word; end; {$PACKRECORDS 2}and Trec2 = Packed Record A : Byte; B : Word; end;Note the {$PACKRECORDS 2} after the first declaration !

Set typesFree Pascal supports the set types as in Turbo Pascal. The prototype of a set declaration is: SetType = Set of TargetType;Each of the elements of SetType must be of type TargetType. TargetType can be any ordinal type with a range between 0 and 255. A set can contain maximally 255 elements. The following is a valid set declaration: Type Days = (Mon, Tue, Wed, Thu, Fri, Sqt, Sun);

Var WeekDays : Set of days;Given this set declaration, the follwing assignment is legal: WeekDays := [ Mon, Tue, Wed, Thu, Fri];The operators for manipulations of sets are listed in table (1.4).   Table 1.4: Set Manipulation operators

Operation Operator Union + Difference - Intersection *

You can compare two sets with the <> and = operators, but not (yet) with the < and > operators. From compiler version 0.9.5, the compiler stores small sets (less than 32 elements) in a longint, if the type range allows it. This allows for faster processing and decreases program size.

Enumeration typesEnumeration types are supported in Free Pascal. On top of the Turbo Pascal implementation, Free Pascal allows the following C-style extension of the enumeration type. Type EnumType = (one, two, three, forty := 40);

Page 100 Free Pascal Manual

Page 101: Free Pascal Manual

As a result, the ordinal number of forty is 40, and not 4, as it would be when the '= 40' wasn't present. When specifying such an enumeration type, it is important to keep in mind that you should keep initialized set elements in ascending order. The following will produce a compiler error: Type EnumType = (one, two, three, forty := 40, thirty:=30);It is necessary to keep forty and Thirty in the correct order. Remark : You cannot use the Pred and Succ functions on this kind of enumeration types. If you try to do that, you'll get a compiler error.

Free Pascal Manual Page 101

Page 102: Free Pascal Manual

CONSTANTSJust as in Turbo Pascal, Free Pascal supports both normal and typed constants.

Ordinary constants Typed constants

Ordinary constantsOrdinary constants declarations are no different from the TP implementation. You can only declare constants of the following types: Ordinal types, Real types, Char, and String. The following are all valid constant declarations: Const e = 2.7182818; { Real type constant. } a = 2; { Integer type constant. } c = '4'; { Character type constant. } s = 'This is a constant string'; {String type constant.}Assigning a value to a constant is not permitted. Thus, given the previous declaration, the following will result in a compiler error: s:='some other string';

Typed constantsTyped constants serve to provide a program with initialized variables. Contrary to ordinary constants, they may be assigned to at run-time. The difference with normal variables is that their value is initialised when the program starts, whereas normal variables must be initialised explicitly. The prototype of a typed constant declaration is: Const SomeConst : SomeType = SomeValue;After that, the constant SomeConst will be of type SomeType, and have initial value SomeValue. Given the declaration: Const S : String = 'This is a typed constant string';The following is a valid assignment: S:='Result : '+Func;Where Func is a function that returns a String. Typed constants also allow you to initialize arrays and records. For arrays, the initial elements must be specified, surrounded by round brackets, and separated by commas. The number of elements must be exactly the same as number of elements in the declaration of the type. As an example: Const tt : array [1..3] of string[20] = ('ikke','gij', 'hij'); ti : array [1..3] of longint = (1,2,3);For constant records, you should specify each element of the record, in the form Field : Value, separated by commas, and surrounded by round brackets. As an example: Type Point = record X,Y : Real end;

Const Origin : Point = (X:0.0 , Y:0.0);The order of the fields in a constant record needs to be the same as in the type declaration, otherwise you'll get a compile-time error.

Page 102 Free Pascal Manual

Page 103: Free Pascal Manual

Free Pascal Manual Page 103

Page 104: Free Pascal Manual

OBJECTSFree Pascal supports object oriented programming. In fact, part of the compiler is written using objects. Here we present some technical questions regarding object oriented programming in Free Pascal. Free Pascal supports 2 programming models for object-oriented programming. You can choose to program object oriented using the Turbo Pascal approach, or you can prefer the Delphi approach.

The Turbo Pascal approach The Delphi approach

The Turbo Pascal approachIn the Turbo Pascal approach, Objects should be treated as a special kind of record. The record contains all the fields that are declared in the objects definition, and pointers to the methods that are associated to the objects' type. An object is declared just as you would declare a record; except that you can now declare procedures and fuctions as of they were part of the record. Objects can ''inherit'' fields and methods from ''parent'' objects. This means that you can use these fields and methods as if the were included in the objects you declared as a ''child'' object. Furthermore, you can declare fields, procedures and functions as public or private. By default, fields and methods are public, and are exported outside the current unit. Fields or methods that are declared private are only accessible in the current unit. The prototype declaration of an object is as follows : TObj = Object [(ParentObjectType)] [Constructor ConstructorName;] [Destructor DestructorName;] Field1 : Type1; ... Fieldn : Typen; Method1; Method2; [private PrField1 : PrType1; ... PrFieldn : PrTypen; PrMethod1; ... PrMethodn;] [public PuField1 : PuType1; .. Pufield1 : PuTypen; PuMethod1; ... PuMethodn;] end;You can repeat as many private and public blocks as you want. Methods are normal function or procedure declarations. As can be seen in the prototype object declaration, Free Pascal supports constructors and destructors. You are responsible for calling the destructor and constructor explicitly when using objects. Free Pascal supports also the extended syntax of the New and Dispose procedures. In case you want to allocate a dynamic varible of an object type, you can specify the constructor's name in the call to New. The New is implemented as a function which returns a pointer to the instantiated object. Given the following declarations : Type

Page 104 Free Pascal Manual

Page 105: Free Pascal Manual

TObj = object; Constructor init; ... end; Pobj = ^TObj;

Var PP : Pobj;Then the following 3 calls are equivalent : pp:=new (Pobj,Init);and new(pp,init);and also new (pp); pp^.init;In the last case, the compiler will issue a warning that you should use the extended syntax of new and dispose to generate instances of an object. You can ignore this warning, but it's better programming practice to use the extended syntax to create instances of an object. Similarly, the Dispose procedure accepts the name of a destructor. The destructor will then be called, before removing the object from the heap. In view of the compiler warning remark, the now following Delphi approach may be considered a more natural way of object-oriented programming.

The Delphi approachIn the Delphi approach to Object Oriented Programming, everything revolves around the concept of 'Classes'. A class can be seen as a pointer to an object, or a pointer to a record. The prototype declaration of a class is as follows : TObj = Class [(ParentClassType)] [Constructor ConstructorName;] [Destructor DestructorName;] Field1 : Type1; ... Fieldn : Typen; Method1; Method2; [private PrField1 : PrType1; ... PrFieldn : PrTypen; PrMethod1; ... PrMethodn;] [public PuField1 : PuType1; .. Pufield1 : PuTypen; PuMethod1; ... PuMethodn;] end;You can repeat as many private and public blocks as you want. Methods are normal function or procedure declarations. As you can see, the declaration of a class is almost identical to the declaration of an object. The real difference between objects and classes is in the way they are created; Classes must be created using their constructor. Remember that A class is a pointer to an object, so

Free Pascal Manual Page 105

Page 106: Free Pascal Manual

when you declare a variable of some class, the compiler just allocates a pointer, not the entire object. The constructor of a class returns a pointer to an initialized instance of the object. So, to initialize an instance of some class, you do the following : ClassVar:=ClassType.ConstructorName;Remark : Free Pascal doesn't support the concept of properties yet.

Page 106 Free Pascal Manual

Page 107: Free Pascal Manual

STATEMENTS CONTROLLING PROGRAM FLOW.

Assignments The Case statement The For..to/downto..do statement The Goto statement The If..then..else statement The Repeat..until statement The While..do statement The With statement Compound statements

AssignmentsIn addition to the standard Pascal assignment operator (:=), Free Pascal supports some c-style constructions. All available constructs are listed in table (1.5).   Table 1.5: Allowed C constructs in Free Pascal

Assignment

Result

a += b Adds b to a, and stores the result in a.

a -= b Substracts b from a, and stores the result in a.

a *= b Multiplies a with b, and stores the result in a.

a /= b Divides a through b, and stores the result in a.

For these connstructs to work, you should specify the -Sc command-line switch. Remark: These constructions are just for typing convenience, they don't generate different code. Free Pascal also supports typed assignments. This means that an assignment statement has a definite type, and hence can be assigned to another variable. The type of the assignment a:=b is the type of a (or, in this case, of b), and this can be assigned to another variable : c:=a:=b;. To summarize: the construct a:=b:=c;results in both a and b being assign the value of c, which may be an expression. For this construct to be allowed, it is necessary to specify the -Sa4 switch on the command line.

The Case statementFree Pascal supports the case statement. Its prototype is Case Pivot of Label1 : Statement1; Label2 : Statement2; ... Labeln : Statementn;[Else AlternativeStatement]end;label1 until Labeln must be known at compile-time, and can be of the following types : enumeration types, Ordinal types (except boolean), and chars. Pivot must also be one of these types. The statements Statement1 etc., can be compound statements (i.e. a begin..End block). Remark: Contrary to Turbo Pascal, duplicate case labels are not allowed in Free Pascal, so the following code will generate an error when compiling: Var i : integer;...

Free Pascal Manual Page 107

Page 108: Free Pascal Manual

Case i of 3 : DoSomething; 1..5 : DoSomethingElse;end;The compiler will generate a Duplicate case label error when compiling this, because the 3 also appears (implicitly) in the range 1..5 Remark: In versions earlier than 0.9.7, there was an incompatibility here with Turbo Pascal. Where in Turbo Pascal you could do the following: case Pivot of ...Else begin Statement1 Statement2 end;You needed to do the following in Free Pascal : case Pivot of ...Else begin Statement1 Statement2 end;end;So there's an extra end keyword at the end. But from version 0.9.7 this has been fixed.

The For..to/downto..do statementFree Pascal supports the For loop construction. The prototypes are: For Counter:=Lowerbound to Upperbound Do Statement;

or

For Counter:=Upperbound downto Lowerbound Do Statement;Statement can be a compound statement. In the first case, if Lowerbound is larger than Upperbound then Statement will never be executed.

The Goto statementFree Pascal supports the goto jump statement. Its prototype is var jumpto : label...Jumpto : Statement;...Goto jumpto;...The jump label must be defined in the same block as the Goto statement. To be able to use the Goto statement, you need to specify the -Sg compiler switch.

Page 108 Free Pascal Manual

Page 109: Free Pascal Manual

The If..then..else statementThe If .. then .. else.. prototype is: If Expression1 Then Statement1;

or

If Expression2 then Statement2else Statement3;Be aware of the fact that the boolean expressions Expression1 and Expression2 will be short-cut evaluated. (Meaning that the evaluation will be stopped at the point where the outcome is known with certainty) Also, after Statement2, no semicolon (;) is alllowed. All statements can be compound statements.

The Repeat..until statementThe prototype of the Repeat..until statement is Repeat Statement1; Statement2;Until Expression;This will execute Statement1 etc. until Expression evaluates to True. Since Expression is evaluated after the execution of the statements, they are executed at least once. Be aware of the fact that the boolean expressions Expression1 and Expression2 will be short-cut evaluated. (Meaning that the evaluation will be stopped at the point where the outcome is known with certainty)

The While..do statementThe prototype of the While..do statement is While Expression Do Statement;This will execute Statement as long as Expression evaluates to True. Since Expression is evaluated before the execution of Statement, it is possible that Statement isn't executed at all. Statement can be a compound statement. Be aware of the fact that the boolean expressions Expression1 and Expression2 will be short-cut evaluated. (Meaning that the evaluation will be stopped at the point where the outcome is known with certainty)

The With statementThe with statement serves to access the elements of a record, without having to specify the name of the record. Given the declaration: Type Passenger = Record Name : String[30]; Flight : String[10]; end;

Var TheCustomer : Passenger;The following statements are completely equivalent:

Free Pascal Manual Page 109

Page 110: Free Pascal Manual

TheCustomer.Name:='Michael';TheCustomer.Flight:='PS901';and With TheCustomer do begin Name:='Michael'; Flight:='PS901'; end;

Compound statementsCompound statements are a group of statements, separated by semicolons, that are surrounded by the keywords Begin and End. The Last statement doesn't need to be followed by a semicolon, although it is allowed.

Page 110 Free Pascal Manual

Page 111: Free Pascal Manual

USING FUNCTIONS AND PROCEDURESFree Pascal supports the use of functions and procedures, but with some extras: Function overloading is supported, as well as Const parameters and open arrays. remark: In the subsequent paragraph the word procedure and function will be used interchangeably. The statements made are valid for both.

Function overloading Const parameters Open array parameters

Function overloadingFunction overloading simply means that you can define the same function more than once, but each time with a different set of arguments. When the compiler encounters a unction call, it will look at the function parameters to decide which od the defined function This can be useful if you want to define the same function for different types. For example, if the RTL, the Dec procedure is is defined as: ...Dec(Var I : longint;decrement : longint);Dec(Var I : longint);Dec(Var I : Byte;decrement : longint);Dec(Var I : Byte);...When the compiler encounters a call to the dec function, it wil first search which function it should use. It therefore checks the parameters in your function call, and looks if there is a function definition which maches the specified parameter list. If the compiler finds such a function, a call is inserted to that function. If no such function is found, a compiler error is generated.

Const parametersIn addition to var parameters and normal parameters (call by value, call by reference), Free Pascal also supports Const parameters. You can specify a Const parameter as follows: Function Name (Const S: Type_Of_S) : ResultTypeA constant argument is passed by refenence (i.e. the function or procedure receives a pointer to the passed , but you are not allowed to assign to it, this will result in a compiler error. The main use for this is reducing the stack size, hence improving performance.

Open array parametersFree Pascal supports the passing of open arrays, i.e. You can declare a procedure with an array of unspecified length as a parameter, as in Delphi. The prototype declaration for open array parameters is: Function Func ( ... [Var|Const] Ident : Array of Type ...) : ReturnType;

ProcedureFunction Func (... [Var|Const] Ident : Array of Type ...);The [Var|Const] means that open parameters can be passed by reference or as a constant parameter. In a function or procedure, you can pass open arrays only to functions which are also declared with open arrays as parameters, not to functions or procedures which accept arrays of fixed length.

Free Pascal Manual Page 111

Page 112: Free Pascal Manual

USING ASSEMBLER IN YOUR CODEFree Pascal supports the use of assembler in your code, but not inline assembler. assembly functions (i.e. functions declared with the Assembler keyword) are supported as of version 0.9.7. Remark : Free Pascal issues AT&T assembly language, as understood by most unix assemblers (most notably : GNU as). Intel assembler syntax is available as of version 0.9.8 but the Intel support isn't complete in the sense that it is converted to AT&T syntax, and some constructions aren't supported by the conversion mechanism (see Programmer's guide for more information about this). Therefore all examples of assembly language will be given in AT&T syntax, as it is the 'native' assembly from Free Pascal. The following is an example of assembler inclusion in your code. ... Statements; ... Asm Movl 0,%eax ... end; ... Statements;The assembler instructions between the Asm and end keywords will be inserted in the assembler generated by the compiler. You can still use comditionals in your assembler, the compiler will recognise it, and treat it as any other conditionals. Contrary to Turbo Pascal, it isn't possible (yet) to reference variables by their names in the assembler parts of your code.

Page 112 Free Pascal Manual

Page 113: Free Pascal Manual

MODIFIERSFree Pascal doesn't support all Turbo Pascal modifiers, but does support a number of additional modifiers. They are used mainly for assembler and reference to C object files.

Public cdecl external Export StdCall Alias [RegisterList] Unsupported Turbo Pascal modifiers

PublicThe Public keyword is used to declare a function globally in a unit. This is useful if you don't want a function to be accessible from the unit file, but you do want the function to be accessible from the object file. as an example: Unit someunit;

interface

Function First : Real;

Implementation

Function First : Real;begin First:=0;end;

Function Second : Real; [Public];

begin Second:=1;end;

end.If another program or unit uses this unit, it will not be able to use the function Second, since it isn't declared in the interface part. However, it will be possible to access the function Second at the assembly-language level, by using it's mangled name (Programmer's guide\).

cdecl  The cdecl modifier can be used to declare a function that uses a C type calling convention. This must be used if you wish to acces functions in an object file generated by a C compiler. It allows you to use the function in your code, and at linking time, you must link the object file containing the C implementation of the function or procedure. As an example: program CmodDemo;

{$LINKLIB c}

Free Pascal Manual Page 113

Page 114: Free Pascal Manual

Const P : Pchar = 'This is fun !';

Function strlen (P : Pchar) : Longint; cdecl; external;

begin Writeln ('Length of (',p,') : ',strlen(p))end.When compiling this, and linking to the C-library, you will be able to call the strlen function throughout your program. The external directive tells the compiler that the function resides in an external object filebrary (see 1.7). Remark The parameters in our declaration of the C function should match exactly the ones in the declaration in C. Since C is case sensitive, this means also that the name of the function must be exactly the same.

external  The external modifier can be used to declare a function that resides in an external object file. It allows you to use the function in your code, and at linking time, you must link the object file containing the implementation of the function or procedure. As an example: program CmodDemo;

{$Linklib c}

Const P : Pchar = 'This is fun !';

Function strlen (P : Pchar) : Longint; cdecl; external;

begin Writeln ('Length of (',p,') : ',strlen(p))end.Remark The parameters in our declaration of the external function should match exactly the ones in the declaration in the object file. Since C is case sensitive, this means also that the name of the function must be exactly the same. The external modifier has also an extended syntax:

1.external 'lname';Tells the compiler that the function resides in library 'lname'. The compiler will the automatically link this library to your program.

2.external 'lname' name Fname;Tells the compiler that the function resides in library 'lname', but with name 'Fname'. The compiler will the automatically link this library to your program, and use the correct name for the function.

3. and OS/2 only: external 'lname' Index Ind;Tells the compiler that the function resides in library 'lname', but with indexname Ind. The compiler will the automatically link this library to your program, and use the correct index for the function.

Page 114 Free Pascal Manual

Page 115: Free Pascal Manual

ExportSometimes you must provide a callback function for a C library, or you want your routines to be callable from a C program. Since Free Pascal and C use different calling schemes for functions and procedures, the compiler must be told to generate code that can be called from a C routine. This is where the Export modifier comes in. Contrary to the other modifiers, it must be specified separately, as follows: function DoSquare (X : longint) : longint; export;

begin...end;The square brackets around the modifier are not allowed in this case. Remark: You cannot call an exported function from within Free Pascal programs. If you try to do so, the compiler will complain when compiling your source code. If you do want to call an exported procedure from pascal, you must use a dummy function: Procedure RealDoSomething;begin...end;

Procedure DoSomething; export;

begin RealDoSomething;end;In this example, from your Free Pascal code, you can call the RealDoSomething procedure. If someone wants to link to your code from a C program, he can call the DoSomething procedure. Both calls will have the same effect. Remark: as of version 0.9.8, Free Pascal supports the Delphi cdecl modifier. This modifier works in the same way as the export modifier. More information about these modifiers can be found in the Programmer's guide in the section on the calling mechanism and the chapter on linking.

StdCallAs of version 0.9.8, Free Pascal supports the Delphi stdcall modifier. This modifier does actually nothing, since the Free Pascal compiler by default pushes parameters from right to left on the stack, which is what the modifier does under Delphi (which pushes parameters on the stack from left to right). More information about this modifier can be found in the Programmer's guide in the section on the calling mechanism and the chapter on linking.

AliasThe Alias modifier allows you to specify a different name for a procedure or function. This is mostly useful for referring to this procedure from assembly language constructs. As an example, consider the following program: Program Aliases;

Procedure Printit; [Alias : 'DOIT'];

begin Writeln ('In Printit (alias : "DOIT")');end;

Free Pascal Manual Page 115

Page 116: Free Pascal Manual

begin asm call DOIT end;end.Remark: the specified alias is inserted straight into the assembly code, thus it is case sensitive. The Alias modifier, combined with the Public modifier, make a powerful tool for making externally accessible object files.

[RegisterList]This modifier list is used to indicate the registers that are modified by an assembler block in your code. The compiler stores certain results in the registers. If you modify theregisters in an assembly block, the compiler should, sometimes, be told about it. The prototype syntax of the Registerlist modifier is: asm statementsend; ['register1','register2',...,'registern'];Where 'register' is one of 'EAX',EBX',ECX','EDX' etc.

Unsupported Turbo Pascal modifiersThe modifiers that exist in Turbo pascal, but aren't supported by Free Pascal, are listed in table (1.6).   Table 1.6: Unsupported modifiers

Modifier Why not supported ? Near Free Pascal is a 32-bit compiler.Far Free Pascal is a 32-bit compiler.

External Replaced by C modifier.

Page 116 Free Pascal Manual

Page 117: Free Pascal Manual

REFERENCE : THE SYSTEM UNITThe system unit contains the standard supported functions of Free Pascal. It is the same for all platforms. Basically it is the same as the system unit provided with Borland or Turbo Pascal. Functions are listed in alphabetical order. Arguments to functions or procedures that are optional are put between square brackets. The pre-defined constants and variables are listed in the first section. The second section contains the supported functions and procedures.

Types, Constants and Variables Types Constants Variables

Functions and Procedures Abs Addr Append Arctan Assign Blockread Blockwrite Chdir Chr Close Concat Copy Cos CSeg Dec Delete Dispose DSeg Eof Eoln Erase Exit Exp Filepos Filesize Fillchar Fillword Flush Frac Freemem Getdir Getmem Halt Hi Inc Insert Int IOresult Length Ln Lo Lowercase

Free Pascal Manual Page 117

Page 118: Free Pascal Manual

Mark Maxavail Memavail Mkdir Move New Odd Ofs Ord Paramcount Paramstr Pi Pos Ptr Random Randomize Read Readln Release Rename Reset Rewrite Rmdir Round Runerror Seek SeekEof SeekEoln Seg SetTextBuf Sin SizeOf Sptr Sqr Sqrt SSeg Str Swap Trunc Truncate Upcase Val Write Writeln

Page 118 Free Pascal Manual

Page 119: Free Pascal Manual

TYPES, CONSTANTS AND VARIABLES

Types Constants Variables

TypesThe following integer types are defined in the System unit: shortint = -128..127;longint = $80000000..$7fffffff;integer = -32768..32767;byte = 0..255;word = 0..65535;The following Real types are declared: double = real;{$ifdef VER0_6} extended = real; single = real;{$endif VER0_6}And the following pointer types: pchar = ^char; ppchar = ^pchar;

ConstantsThe following constants for file-handling are defined in the system unit: Const fmclosed = $D7B0; fminput = $D7B1; fmoutput = $D7B2; fminout = $D7B3; fmappend = $D7B4;

filemode : byte = 2;Further, the following general-purpose constants are also defined: const test8086 : byte = 2; { always i386 or newer } test8087 : byte = 3; { Always 387 or higher. emulated if needed. } erroraddr : pointer = nil; errorcode : word = 0; { max level in dumping on error } max_frame_dump : word = 20;

VariablesThe following variables are defined and initialized in the system unit: var output,input,stderr : text; exitproc : pointer;

Free Pascal Manual Page 119

Page 120: Free Pascal Manual

exitcode : word; stackbottom : longint; loweststack : longint;The variables ExitProc, exitcode are used in the Free Pascal exit scheme. It works similarly to the on in Turbo Pascal: When a program halts (be it through the call of the Halt function or Exit or through a run-time error), the exit mechanism checks the value of ExitProc. If this one is non-Nil, it is set to Nil, and the procedure is called. If the exit procedure exits, the value of ExitProc is checked again. If it is non-Nil then the above steps are repeated. So if you want to install your exit procedure, you should save the old value of ExitProc (may be non-Nil, since other units could have set it before you did). In your exit procedure you then restore the value of ExitProc, such that if it was non-Nil the exit-procedure can be called. The ErrorAddr and ExitCode can be used to check for error-conditions. If ErrorAddr is non-Nil, a run-time error has occurred. If so, ExitCode contains the error code. If ErrorAddr is Nil, then ExitCode contains the argument to Halt or 0 if the program terminated normally. ExitCode is always passed to the operating system as the exit-code of your process. Under GO32, the following constants are also defined : const seg0040 = $0040; segA000 = $A000; segB000 = $B000; segB800 = $B800;These constants allow easy access to the bios/screen segment via mem/absolute.

Page 120 Free Pascal Manual

Page 121: Free Pascal Manual

FUNCTIONS AND PROCEDURES

Abs Addr Append Arctan Assign Blockread Blockwrite Chdir Chr Close Concat Copy Cos CSeg Dec Delete Dispose DSeg Eof Eoln Erase Exit Exp Filepos Filesize Fillchar Fillword Flush Frac Freemem Getdir Getmem Halt Hi Inc Insert Int IOresult Length Ln Lo Lowercase Mark Maxavail Memavail Mkdir Move New Odd Ofs Ord Paramcount

Free Pascal Manual Page 121

Page 122: Free Pascal Manual

Paramstr Pi Pos Ptr Random Randomize Read Readln Release Rename Reset Rewrite Rmdir Round Runerror Seek SeekEof SeekEoln Seg SetTextBuf Sin SizeOf Sptr Sqr Sqrt SSeg Str Swap Trunc Truncate Upcase Val Write Writeln

Abs   

DECLARATION:Function Abs (X : Every numerical type) : Every numerical type;

DESCRIPTION:Abs returns the absolute value of a variable. The result of the function has the same type as its argument, which can be any numerical type.

ERRORS:None.

SEE ALSO:Round

Example

Program Example1;

{ Program to demonstrate the Abs function. }

Page 122 Free Pascal Manual

Page 123: Free Pascal Manual

Var r : real; i : integer;

begin r:=abs(-1.0); { r:=1.0 } i:=abs(-21); { i:=21 }end.

Addr   

DECLARATION:Function Addr (X : Any type) : Pointer;

DESCRIPTION:Addr returns a pointer to its argument, which can be any type, or a function or procedure name. The returned pointer isn't typed. The same result can be obtained by the @ operator, which can return a typed pointer (Programmer's guide\).

ERRORS:None

SEE ALSO:SizeOf

Example

Program Example2;

{ Program to demonstrate the Addr function. }

Const Zero : integer = 0;

Var p : pointer; i : Integer;

begin p:=Addr(p); { P points to itself } p:=Addr(I); { P points to I } p:=Addr(Zero); { P points to 'Zero' }end.

Append   

DECLARATION:Procedure Append (Var F : Text) ;

DESCRIPTION:Append opens an existing file in append mode. Any data written to F will be appended to the file. If the file didn't exist, it will be created, contrary to the Turbo Pascal implementation of Append, where a file needed to exist in order to be opened by append. Only text files can be opened in append mode.

Free Pascal Manual Page 123

Page 124: Free Pascal Manual

ERRORS:If the file can't be created, a run-time error will be generated.

SEE ALSO:Rewrite,Append, Reset

Example

Program Example3;

{ Program to demonstrate the Append function. }

Var f : text;

begin Assign (f,'test.txt'); Rewrite (f); { file is opened for write, and emptied } Writeln (F,'This is the first line of text.txt'); close (f); Append(f); { file is opened for write, but NOT emptied. any text written to it is appended.} Writeln (f,'This is the second line of text.txt'); close (f);end.

Arctan   

DECLARATION:Function Arctan (X : Real) : Real;

DESCRIPTION:Arctan returns the Arctangent of X, which can be any real type. The resulting angle is in radial units.

ERRORS:None

SEE ALSO:Sin, Cos

Example

Program Example4;

{ Program to demonstrate the ArcTan function. }

Var R : Real;

begin R:=ArcTan(0); { R:=0 } R:=ArcTan(1)/pi; { R:=0.25 }end.

Page 124 Free Pascal Manual

Page 125: Free Pascal Manual

Assign   

DECLARATION:Procedure Assign (Var F; Name : String) ;

DESCRIPTION:Assign assigns a name to F, which can be any file type. This call doesn't open the file, it just assigns a name to a file variable, and marks the file as closed.

ERRORS:None.

SEE ALSO:Reset, Rewrite, Append

Example

Program Example5;

{ Program to demonstrate the Assign function. }

Var F : text;

begin Assign (F,''); Rewrite (f); { The following can be put in any file by redirecting it from the command line.} Writeln (f,'This goes to standard output !'); Close (f); Assign (F,'Test.txt'); rewrite (f); writeln (f,'This doesn''t go to standard output !'); close (f);end.

Blockread   

DECLARATION:Procedure Blockread (Var F : File; Var Buffer; Var Count : Longint [; var Result : Longint]) ;

DESCRIPTION:Blockread reads count or less records from file F. The result is placed in Buffer, which must contain enough room for Count records. The function cannot read partial records. If Result is specified, it contains the number of records actually read. If Result isn't specified, and less than Count records were read, a run-time error is generated. This behavior can be controlled by the {$i} switch.

ERRORS:If Result isn't specified, then a run-time error is generated if less than count records were read.

SEE ALSO:Blockwrite,Reset, Assign

Example

Free Pascal Manual Page 125

Page 126: Free Pascal Manual

Program Example6;

{ Program to demonstrate the BlockRead and BlockWrite functions. }

Var Fin, fout : File; NumRead,NumWritten : Word; Buf : Array[1..2048] of byte; Total : Longint;

begin Assign (Fin, Paramstr(1)); Assign (Fout,Paramstr(2)); Reset (Fin,1); Rewrite (Fout,1); Total:=0; Repeat BlockRead (Fin,buf,Sizeof(buf),NumRead); BlockWrite (Fout,Buf,NumRead,NumWritten); inc(Total,NumWritten); Until (NumRead=0) or (NumWritten<>NumRead); Write ('Copied ',Total,' bytes from file ',paramstr(1)); Writeln (' to file ',paramstr(2));end.

Blockwrite   

DECLARATION:Procedure Blockwrite (Var F : File; Var Buffer; Var Count : Longint) ;

DESCRIPTION:Blockread writes count records from buffer to the file F. If the records couldn't be written to disk, a run-time error is generated. This behavior can be controlled by the {$i} switch.

ERRORS:A run-time error is generated if, for some reason, the records couldn't be written to disk.

SEE ALSO:Blockread,Reset, Assign For the example, see Blockread.

Chdir   

DECLARATION:Procedure Chdir (const S : string) ;

DESCRIPTION:Chdir changes the working directory of the process to S.

ERRORS:If the directory S doesn't exist, a run-time error is generated.

SEE ALSO:Mkdir, Rmdir

Page 126 Free Pascal Manual

Page 127: Free Pascal Manual

Example

Program Example7;

{ Program to demonstrate the ChDir function. }

begin {$I-} ChDir (ParamStr(1)); if IOresult<>0 then Writeln ('Cannot change to directory : ',paramstr (1));end.

Chr   

DECLARATION:Function Chr (X : byte) : Char;

DESCRIPTION:Chr returns the character which has ASCII value X.

ERRORS:None.

SEE ALSO:Ord,Str

Example

Program Example8;

{ Program to demonstrate the Chr function. }

begin Write (chr(10),chr(13)); { The same effect as Writeln; } end.

Close   

DECLARATION:Procedure Close (Var F : Anyfiletype) ;

DESCRIPTION:Close flushes the buffer of the file F and closes F. After a call to Close, data can no longer be read from or written to F. To reopen a file closed with Close, it isn't necessary to assign the file again. A call to Reset or Rewrite is sufficient.

ERRORS:None.

SEE ALSO:Assign, Reset, Rewrite

Example

Free Pascal Manual Page 127

Page 128: Free Pascal Manual

Program Example9;

{ Program to demonstrate the Close function. }

Var F : text;

begin Assign (f,'Test.txt'); ReWrite (F); Writeln (F,'Some text written to Test.txt'); close (f); { Flushes contents of buffer to disk, closes the file. Omitting this may cause data NOT to be written to disk.}end.

Concat   

DECLARATION:Function Concat (S1,S2 [,S3, ... ,Sn]) : String;

DESCRIPTION:Concat concatenates the strings S1,S2 etc. to one long string. The resulting string is truncated at a length of 255 bytes. The same operation can be performed with the + operation.

ERRORS:None.

SEE ALSO:Copy, Delete, Insert, Pos, Length

Example

Program Example10;

{ Program to demonstrate the Concat function. }Var S : String; begin S:=Concat('This can be done',' Easier ','with the + operator !');end.

Copy   

DECLARATION:Function Copy (Const S : String;Index : Integer;Count : Byte) : String;

DESCRIPTION:Copy returns a string which is a copy if the Count characters in S, starting at position Index. If Count is larger than the length of the string S, the result is truncated.

Page 128 Free Pascal Manual

Page 129: Free Pascal Manual

If Index is larger than the length of the string S, then an empty string is returned.

ERRORS:None.

SEE ALSO:Delete, Insert, Pos

Example

Program Example11;

{ Program to demonstrate the Copy function. }

Var S,T : String;

begin T:='1234567'; S:=Copy (T,1,2); { S:='12' } S:=Copy (T,4,2); { S:='45' } S:=Copy (T,4,8); { S:='4567' }end.

Cos   

DECLARATION:Function Cos (X : real) : Real;

DESCRIPTION:Cos returns the cosine of X, where X is an angle, in radians.

ERRORS:None.

SEE ALSO:Arctan, Sin

Example

Program Example12;

{ Program to demonstrate the Cos function. }

Var R : Real;

begin R:=Cos(Pi); { R:=-1 } R:=Cos(Pi/2); { R:=0 } R:=Cos(0); { R:=1 } end.

CSeg   

DECLARATION:Function CSeg : Word;

Free Pascal Manual Page 129

Page 130: Free Pascal Manual

DESCRIPTION:CSeg returns the Code segment register. In Free Pascal, it returns always a zero, since Free Pascal is a 32 bit compiler.

ERRORS:None.

SEE ALSO:DSeg, Seg, Ofs, Ptr

Example

Program Example13;

{ Program to demonstrate the CSeg function. }

var W : word;

begin W:=CSeg; {W:=0, provided for comppatibility, FPC is 32 bit.}end.

Dec   

DECLARATION:Procedure Dec (Var X : Any ordinal type[; Decrement : Longint]) ;

DESCRIPTION:Dec decreases the value of X with Decrement. If Decrement isn't specified, then 1 is taken as a default.

ERRORS:A range check can occur, or an underflow error, if you try to decrease X below its minimum value.

SEE ALSO:Inc

Example

Program Example14;

{ Program to demonstrate the Dec function. }

Var I : Integer; L : Longint; W : Word; B : Byte; Si : ShortInt;

begin I:=1; L:=2; W:=3; B:=4; Si:=5; Dec (i); { i:=0 }

Page 130 Free Pascal Manual

Page 131: Free Pascal Manual

Dec (L,2); { L:=0 } Dec (W,2); { W:=1 } Dec (B,-2); { B:=6 } Dec (Si,0); { Si:=5 }end.

Delete   

DECLARATION:Procedure Delete (var S : string;Index : Integer;Count : Integer) ;

DESCRIPTION:Delete removes Count characters from string S, starting at position Index. All remaining characters are shifted Count positions to the left, and the length of the string is adjusted.

ERRORS:None.

SEE ALSO:Copy,Pos,Insert

Example

Program Example15;

{ Program to demonstrate the Delete function. }

Var S : String;

begin S:='This is not easy !'; Delete (S,9,4); { S:='This is easy !' }end.

Dispose   

DECLARATION:Procedure Dispose (P : pointer) ;

DESCRIPTION:Dispose releases the memory allocated with a call to New. The pointer P must be typed. The released memory is returned to the heap.

ERRORS:An error will occur if the pointer doesn't point to a location in the heap.

SEE ALSO:New, Getmem, Freemem

Example

Program Example16;

{ Program to demonstrate the Dispose and New functions. }

Type SS = String[20];

Free Pascal Manual Page 131

Page 132: Free Pascal Manual

AnObj = Object I : integer; Constructor Init; Destructor Done; end;

Var P : ^SS; T : ^AnObj; Constructor Anobj.Init;

begin Writeln ('Initializing an instance of AnObj !');end;

Destructor AnObj.Done;

begin Writeln ('Destroying an instance of AnObj !');end; begin New (P); P^:='Hello, World !'; Dispose (P); { P is undefined from here on !} New(T,Init); T^.i:=0; Dispose (T,Done);end.

DSeg   

DECLARATION:Function DSeg : Word;

DESCRIPTION:DSeg returns the data segment register. In Free Pascal, it returns always a zero, since Free Pascal is a 32 bit compiler.

ERRORS:None.

SEE ALSO:CSeg, Seg, Ofs, Ptr

Example

Program Example17;

{ Program to demonstrate the DSeg function. }

Var

Page 132 Free Pascal Manual

Page 133: Free Pascal Manual

W : Word;

begin W:=DSeg; {W:=0, This function is provided for compatibility, FPC is a 32 bit comiler.}end.

Eof   

DECLARATION:Function Eof [(F : Any file type)] : Boolean;

DESCRIPTION:Eof returns True if the file-pointer has reached the end of the file, or if the file is empty. In all other cases Eof returns False. If no file F is specified, standard input is assumed.

ERRORS:None.

SEE ALSO:Eoln, Assign, Reset, Rewrite

Example

Program Example18;

{ Program to demonstrate the Eof function. }

Var T1,T2 : text; C : Char;

begin { Set file to read from. Empty means from standard input.} assign (t1,paramstr(1)); reset (t1); { Set file to write to. Empty means to standard output. } assign (t2,paramstr(2)); rewrite (t2); While not eof(t1) do begin read (t1,C); write (t2,C); end; Close (t1); Close (t2); end.

Eoln   

DECLARATION:Function Eoln [(F : Text)] : Boolean;

Free Pascal Manual Page 133

Page 134: Free Pascal Manual

DESCRIPTION:Eof returns True if the file pointer has reached the end of a line, which is demarcated by a line-feed character (ASCII value 10), or if the end of the file is reached. In all other cases Eof returns False. If no file F is specified, standard input is assumed. It can only be used on files of type Text.

ERRORS:None.

SEE ALSO:Eof, Assign, Reset, Rewrite

Example

Program Example19;

{ Program to demonstrate the Eoln function. }

begin { This program waits for keyboard input. } { It will print True when an empty line is put in, and false when you type a non-empty line. It will only stop when you press enter.} Writeln (eoln);end.

Erase   

DECLARATION:Procedure Erase (Var F : Any file type) ;

DESCRIPTION:Erase removes an unopened file from disk. The file should be assigned with Assign, but not opened with Reset or Rewrite

ERRORS:A run-time error will be generated if the specified file doesn't exist.

SEE ALSO:Assign

Example

Program Example20;

{ Program to demonstrate the Erase function. }

Var F : Text;

begin { Create a file with a line of text in it} Assign (F,'test.txt'); Rewrite (F); Writeln (F,'Try and find this when I''m finished !'); close (f); { Now remove the file } Erase (f);end.

Page 134 Free Pascal Manual

Page 135: Free Pascal Manual

Exit   

DECLARATION:Procedure Exit ([Var X : return type )] ;

DESCRIPTION:Exit exits the current subroutine, and returns control to the calling routine. If invoked in the main program routine, exit stops the program. The optional argument X allows to specify a return value, in the case Exit is invoked in a function. The function result will then be equal to X.

ERRORS:None.

SEE ALSO:Halt

Example

Program Example21;

{ Program to demonstrate the Exit function. }

Procedure DoAnExit (Yes : Boolean);

{ This procedure demonstrates the normal Exit }

begin Writeln ('Hello from DoAnExit !'); If Yes then begin Writeln ('Bailing out early.'); exit; end; Writeln ('Continuing to the end.');end;

Function Positive (Which : Integer) : Boolean;

{ This function demonstrates the extra FPC feature of Exit : You can specify a return value for the function }

begin if Which>0 then exit (True) else exit (False);end;

begin { This call will go to the end } DoAnExit (False); { This call will bail out early } DoAnExit (True); if Positive (-1) then

Free Pascal Manual Page 135

Page 136: Free Pascal Manual

Writeln ('The compiler is nuts, -1 is not positive.') else Writeln ('The compiler is not so bad, -1 seems to be negative.');end.

Exp   

DECLARATION:Function Exp (Var X : real) : Real;

DESCRIPTION:Exp returns the exponent of X, i.e. the number e to the power X.

ERRORS:None.

SEE ALSO:Ln

Example

Program Example22;

{ Program to demonstrate the Exp function. }

begin Writeln (Exp(1):8:2); { Should print 2.72 }end.

Filepos   

DECLARATION:Function Filepos (Var F : Any file type) : Longint;

DESCRIPTION:Filepos returns the current record position of the file-pointer in file F. It cannot be invoked with a file of type Text.

ERRORS:None.

SEE ALSO:Filesize

Example

Program Example23;

{ Program to demonstrate the FilePos function. }

Var F : File of Longint; L,FP : longint; begin { Fill a file with data : Each position contains the position ! }

Page 136 Free Pascal Manual

Page 137: Free Pascal Manual

Assign (F,'test.dat'); Rewrite (F); For L:=0 to 100 do begin FP:=FilePos(F); Write (F,FP); end; Close (F); Reset (F); { If ll goes well, nothing is displayed here. } While not (Eof(F)) do begin FP:=FilePos (F); Read (F,L); if L<>FP then Writeln ('Something is wrong here ! : Got ',l,' on pos ',FP); end; Close (F); Erase (f);end.

Filesize   

DECLARATION:Function Filesize (Var F : Any file type) : Longint;

DESCRIPTION:Filepos returns the total number of records in file F. It cannot be invoked with a file of type Text. (under LINUX, this also means that it cannot be invoked on pipes.) If F is empty, 0 is returned.

ERRORS:None.

SEE ALSO:Filepos

Example

Program Example24;

{ Program to demonstrate the FileSize function. }

Var F : File Of byte; L : File Of Longint;

begin Assign (F,paramstr(1)); Reset (F); Writeln ('File size in bytes : ',FileSize(F)); Close (F); Assign (L,paramstr (1)); Reset (L); Writeln ('File size in Longints : ',FileSize(L));

Free Pascal Manual Page 137

Page 138: Free Pascal Manual

Close (f); end.

Fillchar   

DECLARATION:Procedure Fillchar (Var X;Count : Longint;Value : char or byte); ;

DESCRIPTION:Fillchar fills the memory starting at X with Count bytes or characters with value equal to Value.

ERRORS:No checking on the size of X is done.

SEE ALSO:Fillword, Move

Example

Program Example25;

{ Program to demonstrate the FillChar function. }

Var S : String[10]; I : Byte;begin For i:=10 downto 0 do begin { Fill S with i spaces } FillChar (S,SizeOf(S),' '); { Set Length } S[0]:=chr(i); Writeln (s,'*'); end;end.

Fillword   

DECLARATION:Procedure Fillword (Var X;Count : Longint;Value : Word); ;

DESCRIPTION:Fillword fills the memory starting at X with Count words with value equal to Value.

ERRORS:No checking on the size of X is done.

SEE ALSO:Fillword, Move

Example

Program Example76;

{ Program to demonstrate the FillWord function. }

Page 138 Free Pascal Manual

Page 139: Free Pascal Manual

Var W : Array[1..100] of Word;

begin { Quick initialization of array W } FillWord(W,100,0);end.

Flush   

DECLARATION:Procedure Flush (Var F : Text) ;

DESCRIPTION:Flush empties the internal buffer of file F and writes the contents to disk. The file is not closed as a result of this call.

ERRORS:If the disk is full, a run-time error will be generated.

SEE ALSO:Close

Example

Program Example26;

{ Program to demonstrate the Flush function. }

Var F : Text;

begin { Assign F to standard output } Assign (F,''); Rewrite (F); Writeln (F,'This line is written first, but appears later !'); { At this point the text is in the internal pascal buffer, and not yet written to standard output } Writeln ('This line appears first, but is written later !'); { A writeln to 'output' always causes a flush - so this text is written to screen } Flush (f); { At this point, the text written to F is written to screen. } Write (F,'Finishing '); Close (f); { Closing a file always causes a flush first } Writeln ('off.');end.

Frac   

DECLARATION:Function Frac (X : real) : Real;

Free Pascal Manual Page 139

Page 140: Free Pascal Manual

DESCRIPTION:Frac returns the non-integer part of X.

ERRORS:None.

SEE ALSO:Round, Int

Example

Program Example27;

{ Program to demonstrate the Frac function. }

Var R : Real;

begin Writeln (Frac (123.456):0:3); { Prints O.456 } Writeln (Frac (-123.456):0:3); { Prints -O.456 }end.

Freemem   

DECLARATION:Procedure Freemem (Var P : pointer; Count : longint) ;

DESCRIPTION:Freemem releases the memory occupied by the pointer P, of size Count, and returns it to the heap. P should point to the memory allocated to a dynamical variable.

ERRORS:An error will occur when P doesn't point to the heap.

SEE ALSO:Getmem, New, Dispose

Example

Program Example28;

{ Program to demonstrate the FreeMem and GetMem functions. }

Var P : Pointer; MM : Longint; begin { Get memory for P } MM:=MemAvail; Writeln ('Memory available before GetMem : ',MemAvail); GetMem (P,80); MM:=MM-Memavail; Write ('Memory available after GetMem : ',MemAvail); Writeln (' or ',MM,' bytes less than before the call.'); { fill it with spaces } FillChar (P^,80,' '); { Free the memory again } FreeMem (P,80);

Page 140 Free Pascal Manual

Page 141: Free Pascal Manual

Writeln ('Memory available after FreeMem : ',MemAvail);end.

Getdir   

DECLARATION:Procedure Getdir (drivenr : byte;var dir : string) ;

DESCRIPTION:Getdir returns in dir the current directory on the drive drivenr, where drivenr is 1 for the first floppy drive, 3 for the first hard disk etc. A value of 0 returns the directory on the current disk. On LINUX, drivenr is ignored, as there is only one directory tree.

ERRORS:An error is returned under DOS, if the drive requested isn't ready.

SEE ALSO:Chdir

Example

Program Example29;

{ Program to demonstrate the GetDir function. }

Var S : String;

begin GetDir (0,S); Writeln ('Current directory is : ',S);end.

Getmem   

DECLARATION:Procedure Getmem (var p : pointer;size : longint) ;

DESCRIPTION:Getmem reserves Size bytes memory on the heap, and returns a pointer to this memory in p. If no more memory is available, nil is returned.

ERRORS:None.

SEE ALSO:Freemem, Dispose, New For an example, see Freemem.

Halt   

DECLARATION:Procedure Halt [(Errnum : byte] ;

Free Pascal Manual Page 141

Page 142: Free Pascal Manual

DESCRIPTION:Halt stops program execution and returns control to the calling program. The optional argument Errnum specifies an exit value. If omitted, zero is returned.

ERRORS:None.

SEE ALSO:Exit

Example

Program Example30;

{ Program to demonstrate the Halt function. }

begin Writeln ('Before Halt.'); Halt (1); { Stop with exit code 1 } Writeln ('After Halt doesn''t get executed.');end.

Hi   

DECLARATION:Function Hi (X : Ordinal type) : Word or byte;

DESCRIPTION:Hi returns the high byte or word from X, depending on the size of X. If the size of X is 4, then the high word is returned. If the size is 2 then the high byte is retuned. hi cannot be invoked on types of size 1, such as byte or char.

ERRORS:None

SEE ALSO:Lo

Example

Program Example31;

{ Program to demonstrate the Hi function. }

var L : Longint; W : Word; begin L:=1 Shl 16; { = $10000 } W:=1 Shl 8; { = $100 } Writeln (Hi(L)); { Prints 1 } Writeln (Hi(W)); { Prints 1 }end.

Page 142 Free Pascal Manual

Page 143: Free Pascal Manual

Inc   

DECLARATION:Procedure Inc (Var X : Any ordinal type[; Increment : Longint]) ;

DESCRIPTION:Inc increases the value of X with Increment. If Increment isn't specified, then 1 is taken as a default.

ERRORS:A range check can occur, or an overflow error, if you try to increase X over its maximum value.

SEE ALSO:Dec

Example

Program Example32;

{ Program to demonstrate the Inc function. }

Const C : Cardinal = 1; L : Longint = 1; I : Integer = 1; W : Word = 1; B : Byte = 1; SI : ShortInt = 1; CH : Char = 'A'; begin Inc (C); { C:=2 } Inc (L,5); { L:=6 } Inc (I,-3); { I:=-2 } Inc (W,3); { W:=4 } Inc (B,100); { B:=101 } Inc (SI,-3); { Si:=-2 } Inc (CH,1); { ch:='B' }end.

Insert   

DECLARATION:Procedure Insert (Var Source : String;var S : String;Index : integer) ;

DESCRIPTION:Insert inserts string S in string Source, at position Index, shifting all characters after Index to the right. The resulting string is truncated at 255 characters, if needed.

ERRORS:None.

SEE ALSO:Delete, Copy, Pos

Example

Free Pascal Manual Page 143

Page 144: Free Pascal Manual

Program Example33;

{ Program to demonstrate the Insert function. }

Var S : String;

begin S:='Free Pascal is difficult to use !'; Insert ('NOT ',S,pos('difficult',S)); writeln (s);end.

Int   

DECLARATION:Function Int (X : real) : Real;

DESCRIPTION:Int returns the integer part of any real X, as a real.

ERRORS:None.

SEE ALSO:Frac, Round

Example

Program Example34;

{ Program to demonstrate the Int function. }

begin Writeln (Int(123.456):0:1); { Prints 123.0 } Writeln (Int(-123.456):0:1); { Prints -123.0 }end.

IOresult   

DECLARATION:Function IOresult : Word;

DESCRIPTION:IOresult contains the result of any input/output call, when the {$i-} compiler directive is active, and IO checking is disabled. When the flag is read, it is reset to zero. If IOresult is zero, the operation completed successfully. If non-zero, an error occurred. The following errors can occur: DOS errors : 2

File not found. 3

Page 144 Free Pascal Manual

Page 145: Free Pascal Manual

Path not found. 4

Too many open files. 5

Access denied. 6

Invalid file handle. 12

Invalid file-access mode. 15

Invalid disk number. 16

Cannot remove current directory. 17

Cannot rename across volumes. I/O errors : 100

Error when reading from disk. 101

Error when writing to disk. 102

File not assigned. 103

File not open. 104

File not opened for input. 105

File not opened for output. 106

Invalid number. Fatal errors : 150

Disk is write protected. 151

Unknown device. 152

Drive not ready. 153

Unknown command. 154

CRC check failed. 155

Invalid drive specified.. 156

Seek error on disk. 157

Invalid media type. 158

Sector not found. 159

Printer out of paper. 160

Error when writing to device. 161

Error when reading from device. 162

Free Pascal Manual Page 145

Page 146: Free Pascal Manual

Hardware failure.

ERRORS:None.

SEE ALSO:All I/O functions.

Example

Program Example35;

{ Program to demonstrate the IOResult function. }

Var F : text;

begin Assign (f,paramstr(1)); {$i-} Reset (f); {$i+} If IOresult<>0 then writeln ('File ',paramstr(1),' doesn''t exist') else writeln ('File ',paramstr(1),' exists');end.

Length   

DECLARATION:Function Length (S : String) : Byte;

DESCRIPTION:Length returns the length of the string S, which is limited to 255. If the strings S is empty, 0 is returned. Note: The length of the string S is stored in S[0].

ERRORS:None.

SEE ALSO:Pos

Example

Program Example36;

{ Program to demonstrate the Length function. }

Var S : String; I : Integer; begin S:=''; for i:=1 to 10 do begin S:=S+'*'; Writeln (Length(S):2,' : ',s); end;end.

Page 146 Free Pascal Manual

Page 147: Free Pascal Manual

Ln   

DECLARATION:Function Ln (X : real) : Real;

DESCRIPTION:Ln returns the natural logarithm of the real parameter X. X must be positive.

ERRORS:An run-time error will occur when X is negative.

SEE ALSO:Exp

Example

Program Example37;

{ Program to demonstrate the Ln function. }

begin Writeln (Ln(1)); { Prints 0 } Writeln (Ln(Exp(1))); { Prints 1 }end.

Lo   

DECLARATION:Function Lo (O : Word or Longint) : Byte or Word;

DESCRIPTION:Lo returns the low byte of its argument if this is of type Integer or Word. It returns the low word of its argument if this is of type Longint or Cardinal.

ERRORS:None.

SEE ALSO:Ord, Chr

Example

Program Example38;

{ Program to demonstrate the Lo function. }

Var L : Longint; W : Word;

begin L:=(1 Shl 16) + (1 Shl 4); { $10010 } Writeln (Lo(L)); { Prints 16 } W:=(1 Shl 8) + (1 Shl 4); { $110 }

Free Pascal Manual Page 147

Page 148: Free Pascal Manual

Writeln (Lo(W)); { Prints 16 }end.

Lowercase   

DECLARATION:Function Lowercase (C : Char or String) : Char or String;

DESCRIPTION:Lowercase returns the lowercase version of its argument C. If its argument is a string, then the complete string is converted to lowercase. The type of the returned value is the same as the type of the argument.

ERRORS:None.

SEE ALSO:Upcase

Example

Program Example73;

{ Program to demonstrate the Lowercase function. }

Var I : Longint;

begin For i:=ord('A') to ord('Z') do write (lowercase(chr(i))); Writeln; Writeln (Lowercase('ABCDEFGHIJKLMNOPQRSTUVWXYZ'));end.

Mark   

DECLARATION:Procedure Mark (Var P : Pointer) ;

DESCRIPTION:Mark copies the current heap-pointer to P.

ERRORS:None.

SEE ALSO:Getmem, Freemem, New, Dispose, Maxavail

Example

Program Example39;

{ Program to demonstrate the Mark and Release functions. }

Var P,PP,PPP,MM : Pointer;

Page 148 Free Pascal Manual

Page 149: Free Pascal Manual

begin Getmem (P,100); Mark (MM); Writeln ('Getmem 100 : Memory available : ',MemAvail,' (marked)'); GetMem (PP,1000); Writeln ('Getmem 1000 : Memory available : ',MemAvail); GetMem (PPP,100000); Writeln ('Getmem 10000 : Memory available : ',MemAvail); Release (MM); Writeln ('Released : Memory available : ',MemAvail); { At this point, PP and PPP are invalid ! }end.

Maxavail   

DECLARATION:Function Maxavail : Longint;

DESCRIPTION:Maxavail returns the size, in bytes, of the biggest free memory block in the heap. Remark: The heap grows dynamically if more memory is needed than is available.

ERRORS:None.

SEE ALSO:Release, Memavail,Freemem, Getmem

Example

Program Example40;

{ Program to demonstrate the MaxAvail function. }

Var P : Pointer; I : longint; begin { This will allocate memory until there is no more memory} I:=0; While MaxAvail>=1000 do begin Inc (I); GetMem (P,1000); end; { Default 4MB heap is allocated, so 4000 blocks should be allocated. When compiled with the -Ch10000 switch, the program will be able to allocate 10 block } Writeln ('Allocated ',i,' blocks of 1000 bytes'); end.

Free Pascal Manual Page 149

Page 150: Free Pascal Manual

Memavail   

DECLARATION:Function Memavail : Longint;

DESCRIPTION:Memavail returns the size, in bytes, of the free heap memory. Remark: The heap grows dynamically if more memory is needed than is available.

ERRORS:None.

SEE ALSO:Maxavail,Freemem, Getmem

Example

Program Example41;

{ Program to demonstrate the MemAvail function. }

Var P, PP : Pointer;

begin GetMem (P,100); GetMem (PP,10000); FreeMem (P,100); { Due to the heap fragmentation introduced By the previous calls, the maximum amount of memory isn't equal to the maximum block size available. } Writeln ('Total heap available (Bytes) : ',MemAvail); Writeln ('Largest block available (Bytes) : ',MaxAvail); end.

Mkdir   

DECLARATION:Procedure Mkdir (const S : string) ;

DESCRIPTION:Chdir creates a new directory S.

ERRORS:If a parent-directory of directory S doesn't exist, a run-time error is generated.

SEE ALSO:Chdir, Rmdir For an example, see Rmdir.

Move   

DECLARATION:Procedure Move (var Source,Dest;Count : longint) ;

Page 150 Free Pascal Manual

Page 151: Free Pascal Manual

DESCRIPTION:Move moves Count bytes from Source to Dest.

ERRORS:If either Dest or Source is outside the accessible memory for the process, then a run-time error will be generated. With older versions of the compiler, a segmentation-fault will occur.

SEE ALSO:Fillword, Fillchar

Example

Program Example42;

{ Program to demonstrate the Move function. }

Var S1,S2 : String [30];

begin S1:='Hello World !'; S2:='Bye, bye !'; Move (S1,S2,Sizeof(S1)); Writeln (S2);end.

New   

DECLARATION:Procedure New (Var P : Pointer[, Constructor]) ;

DESCRIPTION:New allocates a new instance of the type pointed to by P, and puts the address in P. If P is an object, then it is possible to specify the name of the constructor with which the instance will be created.

ERRORS:If not enough memory is available, Nil will be returned.

SEE ALSO:Dispose, Freemem, Getmem, Memavail, Maxavail For an example, see Dispose.

Odd   

DECLARATION:Function Odd (X : longint) : Boolean;

DESCRIPTION:Odd returns True if X is odd, or False otherwise.

ERRORS:None.

SEE ALSO:Abs, Ord

Free Pascal Manual Page 151

Page 152: Free Pascal Manual

Example

Program Example43;

{ Program to demonstrate the Odd function. }

begin If Odd(1) Then Writeln ('Everything OK with 1 !'); If Not Odd(2) Then Writeln ('Everything OK with 2 !'); end.

Ofs   

DECLARATION:Function Ofs Var X : Longint;

DESCRIPTION:Ofs returns the offset of the address of a variable. This function is only supported for compatibility. In Free Pascal, it returns always the complete address of the variable, since Free Pascal is a 32 bit compiler.

ERRORS:None.

SEE ALSO:DSeg, CSeg, Seg, Ptr

Example

Program Example44;

{ Program to demonstrate the Ofs function. }

Var W : Pointer;

begin W:=Ofs(W); { W contains its own offset. } end.

Ord   

DECLARATION:Function Ord (X : Ordinal type) : Byte;

DESCRIPTION:Ord returns the Ordinal value of a ordinal-type variable X.

ERRORS:None.

SEE ALSO:Chr

Page 152 Free Pascal Manual

Page 153: Free Pascal Manual

Example

Program Example45;

{ Program to demonstrate the Ord function. }

Type TEnum = (Zero, One, Two, Three, Four); Var X : Longint; Y : TEnum; begin X:=125; Writeln (Ord(X)); { Prints 125 } Y:= One; Writeln (Ord(y)); { Prints 1 }end.

Paramcount   

DECLARATION:Function Paramcount : Longint;

DESCRIPTION:Paramcount returns the number of command-line arguments. If no arguments were given to the running program, 0 is returned.

ERRORS:None.

SEE ALSO:Paramstr

Example

Program Example46;

{ Program to demonstrate the ParamCount and ParamStr functions. }Var I : Longint; begin Writeln (paramstr(0),' : Got ',ParamCount,' command-line parameters: '); For i:=1 to ParamCount do Writeln (ParamStr (i));end.

Paramstr   

DECLARATION:Function Paramstr (L : Longint) : String;

Free Pascal Manual Page 153

Page 154: Free Pascal Manual

DESCRIPTION:Paramstr returns the L-th command-line argument. L must be between 0 and Paramcount, these values included. The zeroth argument is the name with which the program was started.

ERRORS:Under Linux, command-line arguments may be longer than 255 characters. In that case, the string is truncated. If you want to access the complete string, you must use the argv pointer to access the real values of the command-line parameters.

SEE ALSO:Paramcount For an example, see Paramcount.

Pi   

DECLARATION:Function Pi : Real;

DESCRIPTION:Pi returns the value of Pi (3.1415926535897932385).

ERRORS:None.

SEE ALSO:Cos, Sin

Example

Program Example47;

{ Program to demonstrate the Pi function. }

begin Writeln (Pi); {3.1415926} Writeln (Sin(Pi));end.

Pos   

DECLARATION:Function Pos (Const Substr : String;Const S : String) : Byte;

DESCRIPTION:Pos returns the index of Substr in S, if S contains Substr. In case Substr isn't found, 0 is returned. The search is case-sensitive.

ERRORS:None

SEE ALSO:Length, Copy, Delete, Insert

Example

Page 154 Free Pascal Manual

Page 155: Free Pascal Manual

Program Example48;

{ Program to demonstrate the Pos function. }

Var S : String;

begin S:='The first space in this sentence is at position : '; Writeln (S,pos(' ',S)); S:='The last letter of the alphabet doesn''t appear in this sentence '; If (Pos ('Z',S)=0) and (Pos('z',S)=0) then Writeln (S);end.

Ptr   

DECLARATION:Function Ptr (Sel,Off : Longint) : Pointer;

DESCRIPTION:Ptr returns a pointer, pointing to the address specified by segmentSel and offset Off. Remark 1: In the 32-bit flat-memory model supported by Free Pascal, this function is obsolete.

ERRORS:Remark 2:

SEE ALSO:The returned address is simply the offset. If you recompile the RTL with -dDoMapping defined, then the compiler returns the following : ptr:=pointer($e0000000+sel shl 4+off) under DOS, or ptr:=pointer(sel shl 4+off) on other OSes. None. Addr

Example

Program Example59;

{ Program to demonstrate the Ptr function. }

Var P : ^String; S : String; begin S:='Hello, World !'; P:=Ptr(Seg(S),Longint(Ofs(S))); {P now points to S !} Writeln (P^);end.

Random   

Free Pascal Manual Page 155

Page 156: Free Pascal Manual

DECLARATION:Function Random [(L : longint)] : Longint or Real;

DESCRIPTION:Random returns a random number larger or equal to 0 and strictly less than L. If the argument L is omitted, a real number between 0 and 1 is returned. (0 included, 1 excluded)

ERRORS:None.

SEE ALSO:Randomize

Example

Program Example49;

{ Program to demonstrate the Random and Randomize functions. }

Var I,Count,guess : Longint; R : Real;

begin Randomize; { This way we generate a new sequence every time the program is run} Count:=0; For i:=1 to 1000 do If Random>0.5 then inc(Count); Writeln ('Generated ',Count,' numbers > 0.5'); Writeln ('out of 1000 generated numbers.'); count:=0; For i:=1 to 5 do begin write ('Guess a number between 1 and 5 : '); readln(Guess); If Guess=Random(5)+1 then inc(count); end; Writeln ('You guessed ',Count,' out of 5 correct.'); end.

Randomize   

DECLARATION:Procedure Randomize ;

DESCRIPTION:Randomize initializes the random number generator of Free Pascal, by giving a value to Randseed, calculated with the system clock.

ERRORS:None.

SEE ALSO:Random For an example, see Random.

Page 156 Free Pascal Manual

Page 157: Free Pascal Manual

Read   

DECLARATION:Procedure Read ([Var F : Any file type], V1 [, V2, ... , Vn]) ;

DESCRIPTION:Read reads one or more values from a file F, and stores the result in V1, V2, etc.; If no file F is specified, then standard input is read. If F is of type Text, then the variables V1, V2 etc. must be of type Char, Integer, Real or String. If F is a typed file, then each of the variables must be of the type specified in the declaration of F. Untyped files are not allowed as an argument.

ERRORS:If no data is available, a run-time error is generated. This behavior can be controlled with the {$i} compiler switch.

SEE ALSO:Readln, Blockread, Write, Blockwrite

Example

Program Example50;

{ Program to demonstrate the Read(Ln) function. }

Var S : String; C : Char; F : File of char; begin Assign (F,'ex50.pp'); Reset (F); C:='A'; Writeln ('The characters before the first space in ex50.pp are : '); While not Eof(f) and (C<>' ') do Begin Read (F,C); Write (C); end; Writeln; Close (F); Writeln ('Type some words. An empty line ends the program.'); repeat Readln (S); until S=''; end.

Readln   

DECLARATION:Procedure Readln [Var F : Text], V1 [, V2, ... , Vn]) ;

DESCRIPTION:Read reads one or more values from a file F, and stores the result in V1, V2, etc. After that it goes to

Free Pascal Manual Page 157

Page 158: Free Pascal Manual

the next line in the file (defined by the LineFeed (#10) character). If no file F is specified, then standard input is read. The variables V1, V2 etc. must be of type Char, Integer, Real, String or PChar.

ERRORS:If no data is available, a run-time error is generated. This behavior can be controlled with the {$i} compiler switch.

SEE ALSO:Read, Blockread, Write, Blockwrite For an example, see Read.

Release   

DECLARATION:Procedure Release (Var P : pointer) ;

DESCRIPTION:Release sets the top of the Heap to the location pointed to by P. All memory at a location higher than P is marked empty.

ERRORS:A run-time error will be generated if P points to memory outside the heap.

SEE ALSO:Mark, Memavail, Maxavail, Getmem, Freemem New, Dispose For an example, see Mark.

Rename   

DECLARATION:Procedure Rename (Var F : Any Filetype; Const S : String) ;

DESCRIPTION:Rename changes the name of the assigned file F to S. F must be assigned, but not opened.

ERRORS:A run-time error will be generated if F isn't assigned, or doesn't exist.

SEE ALSO:Erase

Example

Program Example77;

{ Program to demonstrate the Rename function. }Var F : Text;

begin Assign (F,paramstr(1)); Rename (F,paramstr(2));end.

Page 158 Free Pascal Manual

Page 159: Free Pascal Manual

Reset   

DECLARATION:Procedure Reset (Var F : Any File Type[; L : longint]) ;

DESCRIPTION:Reset opens a file F for reading. F can be any file type. If F is an untyped or typed file, then it is opened for reading and writing. If F is an untyped file, the record size can be specified in the optional parameter L. Default a value of 128 is used.

ERRORS:If the file cannot be opened for reading, then a run-time error is generated. This behavior can be changed by the {$i} compiler switch.

SEE ALSO:Rewrite, Assign, Close

Example

Program Example51;

{ Program to demonstrate the Reset function. }

Function FileExists (Name : String) : boolean;

Var F : File;

begin {$i-} Assign (F,Name); Reset (F); {$I+} FileExists:=(IoResult=0) and (Name<>''); Close (f);end;

begin If FileExists (Paramstr(1)) then Writeln ('File found') else Writeln ('File NOT found');end.

Rewrite   

DECLARATION:Procedure Rewrite (Var F : Any File Type[; L : longint]) ;

DESCRIPTION:Rewrite opens a file F for writing. F can be any file type. If F is an untyped or typed file, then it is opened for reading and writing. If F is an untyped file, the record size can be specified in the optional parameter L. Default a value of 128 is used. if Rewrite finds a file with the same name as F, this file is truncated to length 0. If it doesn't find such

Free Pascal Manual Page 159

Page 160: Free Pascal Manual

a file, a new file is created.

ERRORS:If the file cannot be opened for writing, then a run-time error is generated. This behavior can be changed by the {$i} compiler switch.

SEE ALSO:Reset, Assign, Close

Example

Program Example52;

{ Program to demonstrate the Rewrite function. }

Var F : File; I : longint;

begin Assign (F,'Test.dat'); { Create the file. Recordsize is 4 } Rewrite (F,Sizeof(I)); For I:=1 to 10 do BlockWrite (F,I,1); close (f); { F contains now a binary representation of 10 longints going from 1 to 10 }end.

Rmdir   

DECLARATION:Procedure Rmdir (const S : string) ;

DESCRIPTION:Rmdir removes the directory S.

ERRORS:If S doesn't exist, or isn't empty, a run-time error is generated.

SEE ALSO:Chdir, Rmdir

Example

Program Example53;

{ Program to demonstrate the MkDir and RmDir functions. }

Const D : String[8] = 'TEST.DIR';

Var S : String;

begin Writeln ('Making directory ',D); Mkdir (D); Writeln ('Changing directory to ',D); ChDir (D);

Page 160 Free Pascal Manual

Page 161: Free Pascal Manual

GetDir (0,S); Writeln ('Current Directory is : ',S); WRiteln ('Going back'); ChDir ('..'); Writeln ('Removing directory ',D); RmDir (D);end.

Round   

DECLARATION:Function Round (X : real) : Longint;

DESCRIPTION:Round rounds X to the closest integer, which may be bigger or smaller than X.

ERRORS:None.

SEE ALSO:Frac, Int, Trunc

Example

Program Example54;

{ Program to demonstrate the Round function. }

begin Writeln (Round(123.456)); { Prints 124 } Writeln (Round(-123.456)); { Prints -124 } Writeln (Round(12.3456)); { Prints 12 } Writeln (Round(-12.3456)); { Prints -12 }end.

Runerror   

DECLARATION:Procedure Runerror (ErrorCode : Word) ;

DESCRIPTION:Runerror stops the execution of the program, and generates a run-time error ErrorCode.

ERRORS:None.

SEE ALSO:Exit, Halt

Example

Program Example55;

{ Program to demonstrate the RunError function. }

begin { The program will stop end emit a run-error 106 }

Free Pascal Manual Page 161

Page 162: Free Pascal Manual

RunError (106);end.

Seek   

DECLARATION:Procedure Seek (Var F; Count : Longint) ;

DESCRIPTION:Seek sets the file-pointer for file F to record Nr. Count. The first record in a file has Count=0. F can be any file type, except Text. If F is an untyped file, with no specified record size, 128 is assumed.

ERRORS:A run-time error is generated if Count points to a position outside the file, or the file isn't opened.

SEE ALSO:Eof, SeekEof, SeekEoln

Example

Program Example56;

{ Program to demonstrate the Seek function. }

Var F : File; I,j : longint; begin { Create a file and fill it with data } Assign (F,'test.dat'); Rewrite(F); { Create file } Close(f); FileMode:=2; ReSet (F,Sizeof(i)); { Opened read/write } For I:=0 to 10 do BlockWrite (F,I,1); { Go Back to the begining of the file } Seek(F,0); For I:=0 to 10 do begin BlockRead (F,J,1); If J<>I then Writeln ('Error: expected ' ,i,', got ',j); end; Close (f);end.

SeekEof   

Page 162 Free Pascal Manual

Page 163: Free Pascal Manual

DECLARATION:Function SeekEof [(Var F : text)] : Boolean;

DESCRIPTION:SeekEof returns True is the file-pointer is at the end of the file. It ignores all whitespace. Calling this function has the effect that the file-position is advanced until the first non-whitespace character or the end-of-file marker is reached. If the end-of-file marker is reached, True is returned. Otherwise, False is returned. If the parameter F is omitted, standard Input is assumed.

ERRORS:A run-time error is generated if the file F isn't opened.

SEE ALSO:Eof, SeekEoln, Seek

Example

Program Example57;

{ Program to demonstrate the SeekEof function. }Var C : Char;

begin { this will print all characters from standard input except Whitespace characters. } While Not SeekEof do begin Read (C); Write (C); end;end.

SeekEoln   

DECLARATION:Function SeekEoln [(Var F : text)] : Boolean;

DESCRIPTION:SeekEoln returns True is the file-pointer is at the end of the current line. It ignores all whitespace. Calling this function has the effect that the file-position is advanced until the first non-whitespace character or the end-of-line marker is reached. If the end-of-line marker is reached, True is returned. Otherwise, False is returned. The end-of-line marker is defined as #10, the LineFeed character. If the parameter F is omitted, standard Input is assumed.

ERRORS:A run-time error is generated if the file F isn't opened.

SEE ALSO:Eof, SeekEof, Seek

Example

Program Example58;

{ Program to demonstrate the SeekEoln function. }Var

Free Pascal Manual Page 163

Page 164: Free Pascal Manual

C : Char;

begin { This will read the first line of standard output and print all characters except whitespace. } While not SeekEoln do Begin Read (c); Write (c); end;

end.

Seg   

DECLARATION:Function Seg Var X : Longint;

DESCRIPTION:Seg returns the segment of the address of a variable. This function is only supported for compatibility. In Free Pascal, it returns always 0, since Free Pascal is a 32 bit compiler, segments have no meaning.

ERRORS:None.

SEE ALSO:DSeg, CSeg, Ofs, Ptr

Example

Program Example60;

{ Program to demonstrate the Seg function. }Var W : Word;

begin W:=Seg(W); { W contains its own Segment}end.

SetTextBuf   

DECLARATION:Procedure SetTextBuf (Var f : Text; Var Buf[; Size : Word]) ;

DESCRIPTION:SetTextBuf assigns an I/O buffer to a text file. The new buffer is located at Buf and is Size bytes long. If Size is omitted, then SizeOf(Buf) is assumed. The standard buffer of any text file is 128 bytes long. For heavy I/0 operations this may prove too slow. The SetTextBuf procedure allows you to set a bigger buffer for your application, thus reducing the number of system calls, and thus reducing the load on the system resources. The maximum size of the newly assigned buffer is 65355 bytes. Remark 1: Never assign a new buffer to an opened file. You can assign a new buffer immediately after a call to Rewrite, Reset or Append, but not after you read from/wrote to the file. This may cause loss of

Page 164 Free Pascal Manual

Page 165: Free Pascal Manual

data. If you still want to assign a new buffer after read/write operations have been performed, flush the file first. This will ensure that the current buffer is emptied. Remark 2: Take care that the buffer you assign is always valid. If you assign a local variable as a buffer, then after your program exits the local program block, the buffer will no longer be valid, and stack problems may occur.

ERRORS:No checking on Size is done.

SEE ALSO:Assign, Reset, Rewrite, Append

Example

Program Example61;

{ Program to demonstrate the SetTextBuf function. }

Var Fin,Fout : Text; Ch : Char; Bufin,Bufout : Array[1..10000] of byte; begin Assign (Fin,paramstr(1)); Reset (Fin); Assign (Fout,paramstr(2)); Rewrite (Fout); { This is harmless before IO has begun } { Try this program again on a big file, after commenting out the following 2 lines and recompiling it. } SetTextBuf (Fin,Bufin); SetTextBuf (Fout,Bufout); While not eof(Fin) do begin Read (Fin,ch); write (Fout,ch); end; Close (Fin); Close (Fout);end.

Sin   

DECLARATION:Function Sin (X : real) : Real;

DESCRIPTION:Sin returns the sine of its argument X, where X is an angle in radians.

ERRORS:None.

SEE ALSO:Cos, Pi, Exp

Example

Free Pascal Manual Page 165

Page 166: Free Pascal Manual

Program Example62;

{ Program to demonstrate the Sin function. }

begin Writeln (Sin(Pi):0:1); { Prints 0.0 } Writeln (Sin(Pi/2):0:1); { Prints 1.0 }end.

SizeOf   

DECLARATION:Function SizeOf (X : Any Type) : Longint;

DESCRIPTION:SizeOf Returns the size, in bytes, of any variable or type-identifier. Remark: this isn't really a RTL function. Its result is calculated at compile-time, and hard-coded in your executable.

ERRORS:None.

SEE ALSO:Addr

Example

Program Example63;

{ Program to demonstrate the SizeOf function. }Var I : Longint; S : String [10];

begin Writeln (SizeOf(I)); { Prints 4 } Writeln (SizeOf(S)); { Prints 11 }end.

Sptr   

DECLARATION:Function Sptr : Pointer;

DESCRIPTION:Sptr returns the current stack pointer.

ERRORS:None.

SEE ALSO:Example

Program Example64;

{ Program to demonstrate the SPtr function. }

Page 166 Free Pascal Manual

Page 167: Free Pascal Manual

Var P :Longint;

begin P:=Sptr; { P Contains now the current stack position. }end.

Sqr   

DECLARATION:Function Sqr (X : Real) : Real;

DESCRIPTION:Sqr returns the square of its argument X.

ERRORS:None.

SEE ALSO:Sqrt, Ln, Exp

Example

Program Example65;

{ Program to demonstrate the Sqr function. }Var i : Integer; begin For i:=1 to 10 do writeln (Sqr(i):3);end.

Sqrt   

DECLARATION:Function Sqrt (X : Real) : Real;

DESCRIPTION:Sqrt returns the square root of its argument X, which must be positive.

ERRORS:If X is negative, then a run-time error is generated.

SEE ALSO:Sqr, Ln, Exp

Example

Program Example66;

{ Program to demonstrate the Sqrt function. }

begin Writeln (Sqrt(4):0:3); { Prints 2.000 }

Free Pascal Manual Page 167

Page 168: Free Pascal Manual

Writeln (Sqrt(2):0:3); { Prints 1.414 }end.

SSeg   

DECLARATION:Function SSeg : Longint;

DESCRIPTION:SSeg returns the Stack Segment. This function is only supported for compatibolity reasons, as Sptr returns the correct contents of the stackpointer.

ERRORS:None.

SEE ALSO:Sptr

Example

Program Example67;

{ Program to demonstrate the SSeg function. }Var W : Longint;

begin W:=SSeg; end.

Str   

DECLARATION:Procedure Str (Var X[:NumPlaces[:Decimals]]; Var S : String) ;

DESCRIPTION:Str returns a string which represents the value of X. X can be any numerical type. The optional NumPLaces and Decimals specifiers control the formatting of the string.

ERRORS:None.

SEE ALSO:Val

Example

Program Example68;

{ Program to demonstrate the Str function. }Var S : String;

Function IntToStr (I : Longint) : String;

Var S : String;

begin

Page 168 Free Pascal Manual

Page 169: Free Pascal Manual

Str (I,S); IntToStr:=S;end;

begin S:='*'+IntToStr(-233)+'*'; Writeln (S);end.

Swap   

DECLARATION:Function Swap (X) : Type of X;

DESCRIPTION:Swap swaps the high and low order bytes of X if X is of type Word or Integer, or swaps the high and low order words of X if X is of type Longint or Cardinal. The return type is the type of X

ERRORS:None.

SEE ALSO:Lo, Hi

Example

Program Example69;

{ Program to demonstrate the Swap function. }Var W : Word; L : Longint; begin W:=$1234; W:=Swap(W); if W<>$3412 then writeln ('Error when swapping word !'); L:=$12345678; L:=Swap(L); if L<>$56781234 then writeln ('Error when swapping Longint !');end.

Trunc   

DECLARATION:Function Trunc (X : real) : Longint;

DESCRIPTION:Trunc returns the integer part of X, which is always smaller than (or equal to) X.

ERRORS:None.

Free Pascal Manual Page 169

Page 170: Free Pascal Manual

SEE ALSO:Frac, Int, Trunc

Example

Program Example54;

{ Program to demonstrate the Trunc function. }

begin Writeln (Trunc(123.456)); { Prints 123 } Writeln (Trunc(-123.456)); { Prints -123 } Writeln (Trunc(12.3456)); { Prints 12 } Writeln (Trunc(-12.3456)); { Prints -12 }end.

Truncate   

DECLARATION:Procedure Truncate (Var F : file) ;

DESCRIPTION:Truncate truncates the (opened) file F at the current file position.

ERRORS:Errors are reported by IOresult.

SEE ALSO:Append, Filepos, Seek

Example

Program Example71;

{ Program to demonstrate the Truncate function. }

Var F : File of longint; I,L : Longint; begin Assign (F,'test.dat'); Rewrite (F); For I:=1 to 10 Do Write (F,I); Writeln ('Filesize before Truncate : ',FileSize(F)); Close (f); Reset (F); Repeat Read (F,I); Until i=5; Truncate (F); Writeln ('Filesize after Truncate : ',Filesize(F)); Close (f);end.

Page 170 Free Pascal Manual

Page 171: Free Pascal Manual

Upcase   

DECLARATION:Function Upcase (C : Char or string) : Char or String;

DESCRIPTION:Upcase returns the uppercase version of its argument C. If its argument is a string, then the complete string is converted to uppercase. The type of the returned value is the same as the type of the argument.

ERRORS:None.

SEE ALSO:Lowercase

Example

Program Example72;

{ Program to demonstrate the Upcase function. }

Var I : Longint;

begin For i:=ord('a') to ord('z') do write (upcase(chr(i))); Writeln; { This doesn't work in TP, but it does in Free Pascal } Writeln (Upcase('abcdefghijklmnopqrstuvwxyz'));end.

Val   

DECLARATION:Procedure Val (const S : string;var V;var Code : word) ;

DESCRIPTION:Val converts the value represented in the string S to a numerical value, and stores this value in the variable V, which can be of type Longint, real and Byte. If the conversion isn't succesfull, then the parameter Code contains the index of the character in S which prevented the conversion. The string S isn't allow to contain spaces.

ERRORS:If the conversion doesn't succeed, the value of Code indicates the position where the conversion went wrong.

SEE ALSO:Str

Example

Program Example74;

{ Program to demonstrate the Val function. }Var I, Code : Integer;

Free Pascal Manual Page 171

Page 172: Free Pascal Manual

begin Val (ParamStr (1),I,Code); If Code<>0 then Writeln ('Error at position ',code,' : ',Paramstr(1)[Code]) else Writeln ('Value : ',I); end.

Write   

DECLARATION:Procedure Write ([Var F : Any filetype;] V1 [; V2; ... , Vn)] ;

DESCRIPTION:Write writes the contents of the variables V1, V2 etc. to the file F. F can be a typed file, or a Text file. If F is a typed file, then the variables V1, V2 etc. must be of the same type as the type in the declaration of F. Untyped files are not allowed. If the parameter F is omitted, standard output is assumed. If F is of type Text, then the necessary conversions are done such that the output of the variables is in human-readable format. This conversion is done for all numerical types. Strings are printed exactly as they are in memory, as well as PChar types. The format of the numerical conversions can be influenced through the following modifiers: OutputVariable : NumChars [: Decimals ] This will print the value of OutputVariable with a minimum of NumChars characters, from which Decimals are reserved for the decimals. If the number cannot be represented with NumChars characters, NumChars will be increased, until the representation fits. If the representation requires less than NumChars characters then the output is filled up with spaces, to the left of the generated string, thus resulting in a right-aligned representation. If no formatting is specified, then the number is written using its natural length, with a space in front of it if it's positive, and a minus sign if it's negative. Real numbers are, by default, written in scientific notation.

ERRORS:If an error occurs, a run-time error is generated. This behavior can be controlled with the {$i} switch.

SEE ALSO:Writeln, Read, Readln, Blockwrite

Writeln   

DECLARATION:Procedure Writeln [([Var F : Text;] [V1 [; V2; ... , Vn)]] ;

DESCRIPTION:Writeln does the same as Write for text files, and emits a Carriage Return - LineFeed character pair after that. If the parameter F is omitted, standard output is assumed. If no variables are specified, a Carriage Return - LineFeed character pair is emitted, resulting in a new line in the file F. Remark: Under LINUX, the Carriage Return character is omitted, as customary in Unix environments.

Page 172 Free Pascal Manual

Page 173: Free Pascal Manual

ERRORS:If an error occurs, a run-time error is generated. This behavior can be controlled with the {$i} switch.

SEE ALSO:Write, Read, Readln, Blockwrite

Example

Program Example75;

{ Program to demonstrate the Write(ln) function. }

Var F : File of Longint; L : Longint; begin Write ('This is on the first line ! '); { No CR/LF pair! } Writeln ('And this too...'); Writeln ('But this is already on the second line...'); Assign (f,'test.dat'); Rewrite (f); For L:=1 to 10 do write (F,L); { No writeln allowed here ! } Close (f);end.

Free Pascal Manual Page 173