User Changes Trunk

From Free Pascal wiki
Revision as of 09:07, 25 November 2019 by Jonas (talk | contribs) (Explicit values for enumeration types are limited to low(longint) ... high(longint))

About this page

Listed below are intentional changes made to the FPC compiler (trunk) since the next upcoming release that may break existing code. The list includes reasons why these changes have been implemented, and suggestions for how you might adapt your code if you find that previously working code has been adversely affected by these recent changes.

The list of new features that do not break existing code can be found here.

Please add revision numbers to the entries from now on. This facilitates moving merged items to the user changes of a release.

All systems

Language Changes

Implementation Changes

Property field access lists no longer allows classes

  • Old behaviour: A field access list for a property is allowed to contain implicit dereferences in the form of fields of class instances.
  • New behaviour: A field access list for a property must only contain record or (TP style) object fields.
  • Reason:
    • Delphi compatibility
    • This resulted in an internal error for published properties
  • Remedy:
    • Switch the fields to records or objects
    • Use a method with inline modifier that will result in similar performance
  • svn: 40656
  • Example: The following code now fails:
unit Test;
{$mode objfpc}


  TTest1 = class
    Field: String;

  TTest2 = class
    fTest1: TTest1;
    property Prop: String read fTest1.Field; // Error "Record or object type expected"



Disabled default support for automatic conversions of regular arrays to dynamic arrays

  • Old behaviour: In FPC and ObjFPC modes, by default the compiler could automatically convert a regular array to a dynamic array.
  • New behaviour: By default, the compiler no longer automatically converts regular arrays to dynamic arrays in any syntax mode.
  • Reason: When passing a dynamic array by value, modifications to its contents by the callee are also visible on the caller side. However, if an array is implicitly converted to a dynamic array, the result is a temporary value and hence changes are lost. This issue came up when adding TStream.Read() overloads.
  • Remedy: Either change the code so it no longer assigns regular arrays to dynamic arrays, or add {$modeswitch arraytodynarray} a
  • Example: this program demonstrates the issue that appeared with the TStream.Read() overloads that were added (originally, only the the version with the untyped variable existed)
{$mode objfpc}
  tdynarray = array of byte;

procedure test(var arr); overload;

procedure test(arr: tdynarray); overload;

  regulararray: array[1..1] of byte;
  writeln(arr[0]); // writes 0, because it calls test(tdynarr)
  • svn: 42118

Range checking for enumeration constants in Delphi mode

  • Old behaviour: Out-of-range enumeration constants never caused an error in Delphi mode, because very early versions of Delphi did not either.
  • New behaviour: Out-of-range enumeration constants cause an error in Delphi mode, even if range checking is disabled. Current Delphi versions (and even older ones, such as Delphi 7) behave the same.
  • Reason: Delphi-compatibility.
  • Remedy: Fix the range errors.
  • svn: 42272, 42275

Directive clause […] no longer useable with modeswitch PrefixedAttributes

  • Old behaviour: A function/procedure/method or procedure/method variable type could be followed by a directive clause in square brackets ([…]) that contains the directives for the routine or type (e.g. calling convention).
  • New behaviour: If the modeswitch PrefixedAttributes is enabled (which is the default in modes Delphi and DelphiUnicode) the directive clause in square brackets is no longer allowed.
  • Reason: As custom attributes are bound to a type/property in a way that looks ambiguous to a directive clause and this ambiguity is not easily solved in the parser it is better to disable this feature.
  • Remedy:
    • don't set (in non-Delphi modes) or disable modeswitch PrefixedAttributes (in Delphi modes) if you don't use attributes ({$modeswitch PrefixedAttributes-})
    • rework your directive clause:
// this
procedure Test; cdecl; [public,alias:'foo']

// becomes this
procedure Test; cdecl; public; alias:'foo';
  • svn: 42402

Type information contains reference to attribute table

  • Old behavior: The first field of the data represented by TTypeData is whatever the sub branch of the case statement for the type contains.
  • New behavior: The first field of the data represented by TTypeData is a reference to the custom attributes that are attributed to the type, only then the type specific fields follow.
  • Reason: Any type can have attributes, so it make sense to provide this is a common location instead of having to parse the different types.
  • Remedy:
    • If you use the records provided by the TypInfo unit no changes should be necessary (same for the Rtti unit).
    • If you directly access the binary data you need handle an additional Pointer field at the beginning of the TTypeData area and possibly correct the alignment for platforms that have strict alignment requirements (e.g. ARM or M68k).
  • svn: 42375

Explicit values for enumeration types are limited to low(longint) ... high(longint)

  • Old behavior: The compiler accepted every integer value as explicit enumeration value. The value was silently reduced to the longint range if it fell out of it.
  • New behavior: The compiler throws an error (FPC mode) or a warning (Delphi mode) if an explicit enumeration value lies outside the longint range.
  • Reason: Type TEnum = (a = $ffffffff); resulted in an enum with size 1 instead of 4 as it would be expected, because the $ffffffff was interpreted as "-1".
  • Remedy: Add a Longint typecasts to values outside the valid range of a Longint.

Unit changes

System - TVariantManager

  • Old behaviour: TVariantManager.olevarfromint has a source parameter of type LongInt.
  • New behaviour: TVariantManager.olevarfromint has a source parameter of type Int64.
  • Reason for change: 64-bit values couldn't be correctly converted to an OleVariant.
  • Remedy: If you implemented your own variant manager then adjust the method signature and handle the range parameter accordingly.
  • svn: 41570

64-bit values in OleVariant

  • Old behaviour: If a 64-bit value (Int64, QWord) is assigned to an OleVariant its type is varInteger and only the lower 32-bit are available.
  • New behaviour: If a 64-bit value (Int64, QWord) is assigned to an OleVariant its type is either varInt64 or varQWord depending on the input type.
  • Reason for change: 64-bit values weren't correctly represented. This change is also Delphi compatible.
  • Remedy: Ensure that you handle 64-bit values correctly when using OleVariant.
  • svn: 41571

Classes TCollection.Move

  • Old behaviour: If a TCollection.Descendant called Move() this would invoke System.Move.
  • New behaviour: If a TCollection.Descendant called Move() this invokes TCollection.Move.
  • Reason for change: New feature in TCollection: move, for consistency with other classes.
  • Remedy: prepend the Move() call with the system unit name: System.move().
  • svn: 41795


TMSSQLConnection uses TDS protocol version 7.3 (MS SQL Server 2008)
  • Old behaviour: TMSSQLConnection used TDS protocol version 7.0 (MS SQL Server 2000).
  • New behaviour: TMSSQLConnection uses TDS protocol version 7.3 (MS SQL Server 2008).
  • Reason for change: native support for new data types introduced in MS SQL Server 2008 (like DATE, TIME, DATETIME2). FreeTDS client library version 0.95 or higher required.
  • svn: 42737

Darwin/macOS platforms

Default Target (Mac) OS X/macOS version

  • Old behaviour: The default target Mac OS X version for the i386 (Intel 32 bits) platform was Mac OS X 10.4, and for the x86-64 (Intel 64 bits) was Mac OS X 10.5.
  • New behaviour: The default target Mac OS X version for both the i386 (Intel 32 bits) and x86-64 (Intel 64 bits) platforms is now OS X 10.8.
  • Reason: On macOS 10.14, installing the command line tools no longer places the ctr*.o files required when targeting the older Mac OS X targets in the same location as before, resulting in the need for custom command line options and modifications to fpc.cfg.
  • Remedy: If you wish to target those earlier Mac OS X versions, use the -WM10.4 resp. -WM10.5 command line parameters of the compiler, and if necessary point it to an SDK that still contains support for those Mac OS X versions with the -XR/path/to/SDK parameter (and, if necessary, to an assembler/linker that supports removed architectures with -FD/path/to/clang_and_ld).
  • svn: 43374

Previous release notes