User Changes 2.2.0

From Lazarus wiki
Revision as of 10:30, 17 February 2007 by Daniel-fpc (talk | contribs) (GPC mode)
Jump to navigationJump to search

About this page

Below you can find a list of intentional changes since the FPC 2.0.4 release which can change the behaviour of previously working code, along with why these changes were performed and how you can adapt your code if you are affected by them.

All systems

Floating point constants

  • Old behaviour: all floating point constants were considered to be of the highest precision available on the target platform
  • New behaviour: floating point constants are now considered to be of the lowest precision which doesn't cause data loss
  • Example: 2.0 can be represented exactly using single, so it will be parsed as a single. 1.1 cannot be represented exactly in any IEEE floating point format, so it will be considered to be of the largest floating point type available
  • Reason: Delphi compatibility, avoid wrong precision-loss warnings when doing things like "singler:=single1*2.0"
  • Effect: some expressions, in particular divisions of integer values by floating point constants, may now default to a lower precision than in the past.
  • Remedy: if more precision is required than the default, typecast the floating point constant to a higher precision type, e.g. extended(2.0)

Pure assembler routines in Delphi mode

  • Old behaviour: a stack frame was always created, unless the procedure declaration was followed by nostackframe
  • New behaviour: in Delphi mode, pure assembler functions no longer get a stack frame if all parameters are passed in registers, and if the @result/__result symbol is not referenced. On systems which require the stack to be aligned when performing a subroutine call (e.g., Darwin/i386), this stack alignment is still performed unless you use the "nostackframe" directive.
  • Example: function f(l1,l2,l3: longint): longint; asm end; used to get a stack frame in on i386 in Delphi mode. Now it doesn't anymore.
  • Reason: Delphi compatibility
  • Effect: assembler routines which depended on getting a compiler-generated stack frame may no longer work in Delphi mode
  • Remedy: do not use Delphi mode, turn the routine into an regular procedure/function with an embedded assembler block, rewrite the routine so it works without a stack frame, or explicitly reference the @result/__result symbol in the assembler code


  • Old behaviour: you had to call RTLEventStartWait before calling RTLEventWaitFor
  • New behaviour: RTLEventStartWait has been removed from the RTL
  • Example: self-explanatory
  • Reason: RTLEventStartWait only existed because the Unix implementation did not support persistent events. Now it does, so this routine is no longer necessary.
  • Effect: code calling RTLEventStartWait will no longer compile
  • Remedy: remove all calls to RTLEventStartWait from your code, they are no longer necessary

"In" operations

  • Old behaviour: an "in" operation always automatically converted the left operand to a byte-sized entity, just like Turbo Pascal
  • New behaviour: the above is now only done in the TP compatibility mode. In other syntax modes, the full size of the left operand is kept (but sets with more than 256 elements are not yet fully supported)
  • Example: in previous versions, word_var:=256; writeln(word_var in [0,1]); wrote TRUE if range checking was off, and generated a range check error if range checking was on. In 2.2.0, that behaviour is still the same in {$mode tp}, but in other modes it will write FALSE and never generate a range check error.
  • Reason: Delphi compatibility for {$mode delphi}, and and also in FPC/OBJFPC/MACPAS modes because the new behaviour is more intuitive.
  • Effect: non-TP mode code relying on 256 in [0,1]-like behaviour will no longer work.
  • Workaround: compile in TP mode, typecast the left operand of your in-statements to a byte, or change the logic of your program to work with the new behaviour.

MacPas OSType/FourCharCode

  • Old behaviour: strings could be implicitly converted to 32 bit integer values by the compiler in macpas mode (i.e., without a typecast)
  • New behaviour: only constant strings of exactly 4 characters can be implicitly converted to 32 bit integers
  • Example: dword1:=stringvar; and dword1:='ab'; used to compile in macpas mode, now this will give a compile time error. dword1:='abcd'; will still work, however.
  • Reason: although those statements (and others, like indexing a dword as an array) are allowed by e.g. Metrowerks Pascal, they go against all Pascal typing rules. Some, like the indexing of dwords as arrays, are also inherently endian-unsafe.
  • Effect: code using such constructs will no longer compile
  • Workaround: use the function FOUR_CHAR_CODE(const literal: string): LongWord; function in places where you still want to convert strings to OSType. This function will also take care of endian issues.

GPC mode

  • New behavour: GPC mode has been disabled.
  • Reason: It only disabled as many features as possible which little to do with GPC compatibility.
  • Effect: {$mode gpc} will no longer work, -mgpc will no longer word.
  • Workaround: Use a different mode, FPC mode is closest.


RTLEvent persistence

  • Old behaviour: calling RTLEventSetEvent before another thread was waiting caused the event to be lost
  • New behaviour: RTLEventSetEvent is now persistent, i.e. it's possible to send the event before another thread starts waiting and it won't be lost (calling RTLEventSetEvent multiple times does not cause multiple events to add up in a queue)
  • Example: see above
  • Reason: compatibility with behaviour under Windows
  • Effect: see above
  • Remedy: for non-persistent events, use the pthread_cond_signal/wait and related routines directly


Floating point calculations

  • Old behaviour: all floating point calculations used to be performed using double precision
  • New behaviour: floating point calculations involving only single precision values are now performed using single precision
  • Example: singler:=(single1/single2+single3)*single4 used to be calculated using double precision, and only be rounded back to single precision during the assignment. Now the intermediate calculations will also be done using single precision.
  • Reason: speed (in particular single precision divisions are much faster than double precision ones), compatibility with gcc behaviour
  • Effect & Remedy: see "Floating point constants" section

64 Bit systems

Vararray indicies

  • Old behaviour: varrays (arrays stored in variants) used 64 bit indicies
  • New behaviour: now they use 32 bit indicies only because this how it works on win64
  • Reason: Variants are something very windows specific so we modell them after windows