Free Pascal/Lazarus gotchas
April 4th, 2016

In my experience, moving from Delphi to Lazarus is mostly painless, and in some respects quite enjoyable. But there are small differences that can be the source of some head scratching. Here are some "gotchas" that have tricked me in the past and sometimes still trip me up.

Assigning procedural types and event handlers in objfpc mode vs in Delphi mode.

In objfpc mode, procedural types must be assigned with the address operator @ as clearly indicated in the manual. The operator is not necessary in delphi or turbo pascal mode. Event handlers are procedural types so the same applies to them. However in that case, the error message Error: Wrong number of parameters specified for call to "EditChange" often confuses me and sends me on a wild goose chase counting parameters and wondering why there is a problem. After all, the handler EditChange has exactly one parameter as expected of a TNotifyEvent handler.

Recursion in objfpc mode vs in Delphi mode.

A function without parameters will not call itself recursively unless parenthesis are appended to the function name :

function myFunction: integer; begin ... result := 32 * myFunction(); // don’t forget the ()! ... end;

This C style calling convention is not necessary in Delphi and is not necessary in a Free Pascal program if Delphi mode {$mode Delphi} is used instead of the default {$mode objfpc}.

Run-time assignment of procedural types objfpc mode vs in Delphi mode

This is pretty much the same gotcha as above. If a procedure type is defined for functions without parameters, is will be necessary to append parenthesis to the procedural variable to invoke the function in objfpc mode.

type TFunctionType = function: integer; var aFunction: TFunctionType; begin aFunction := @recur2; Label1.Caption := 'recur2 = ' + inttostr(aFunction());// Don't forget the ()!

No Debug and Release build modes.

Debug and release build modes are not defined by default in a new project. However, they are easily created by checking the Build modes in Options for MyProject. You can get to that window in the Lazarus IDE by selecting the following menu choices: Project / Project Options ... / Compiler Options. A Build Mode window will appear. Click on the Create Debug and Release modes button to add these two build modes to the Default mode.

DEBUG and RELEASE symbols not defined in corresponding build modes.

To add these symbols, click on the Custom Options choice in the CompilerOptions (see above). Then click on the Defines... button and add the two symbols DEBUG and RELEASE. Close the Defines window by clicking on the Ok button and the select the Debug mode in the build mode combo box at the top. Click on the Defines... button again and check the DEBUG symbol and uncheck the RELEASE symbol if necessary and click on the Ok button. The Custom options memo should then show -dDEBUG. Select the Release build mode and click on Defines... and this time check the RELEASE and uncheck the DEBUG symbols. Then -dRELEASE should appear in the Custom options memo once the Defines window is closed.

This procedure is valid for Lazarus version 1.6. You could probably add the -dDEBUG and -dRELEASE defines directly in the custom options memo. I seem to recall that was how it was done in version 1.4.

Demonstration program

The archive contains a small program illustrating these problems and solutions. Be sure to run the program four times, once with the directive {$mode objfpc} defined and {$mode delphi} undefined and again inverting these defines in Unit1.pas and then again in Unit2.pas. The debug and release build modes are defined in this project along with the corresponding DEBUG and RELEASE symbols.