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.
Table of Contents
- Assigning Procedural Variables in
objfpc
Mode - Recursion in
objfpc
Mode - Assigning Procedural Variables at Run-Time in
objfpc
Mode - No Debug and Release Build Modes
- Demonstration Program
Assigning Procedural Variable in objfpc
Mode
Procedural variables must be assigned with the address operator @ in fpc
and objfpc
modes. This is clearly indicated in the Free Pascal Programmer's Guide: D.1 FPC mode and D.5 OBJFPC mode. The operator is not necessary in delphi
or tp
(Turbo Pascal 7) mode. Object event handler variables are procedural variables 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
A function without parameters will not call itself recursively unless parenthesis are appended to the function name :
This C style calling convention is not necessary in Delphi and is not necessary in a Free Pascal program if delphi
mode ({$mode delphi}
, not case sensitive) is used instead of the default {$mode objfpc}
.
Assigning Procedural Variable at run-time in objfpc
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.
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.
Even when these modes are enabled, the 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 gotcha.zip 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
directives.