Difference between revisions of "User Changes Trunk"

From Lazarus wiki
Jump to navigationJump to search
m (Fix typos)
 
(155 intermediate revisions by 16 users not shown)
Line 1: Line 1:
 
== About this page==
 
== About this page==
  
Listed below are intentional changes made to the FPC compiler (trunk) since the [[User_Changes_2.6.4|previous 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.  
+
Listed below are intentional changes made to the FPC compiler (trunk) since the [[User_Changes_3.2.2|previous 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 [[FPC_New_Features_Trunk|here]].
 
The list of new features that do not break existing code can be found [[FPC_New_Features_Trunk|here]].
Line 9: Line 9:
 
== All systems ==
 
== All systems ==
  
=== Implementation changes ===
+
=== Language Changes ===
  
==== Exception type for object reference checking changed ====
+
==== Precedence of the IS operator changed ====
* '''Old behaviour''': When object reference checking (''-CR'' or ''{$OBJECTCHECKS ON}'') is enabled and the unit ''SysUtils'' is used then an exception of class ''Exception'' with localizeable message ''Unknown runtime error 210'' is created.
+
* '''Old behaviour''': The IS operator had the same precedence as the multiplication, division etc. operators.
* '''New behaviour''': Now an exception of class ''EObjectCheck'' with localizeable message ''Object reference is Nil'' is created.
+
* '''New behaviour''': The IS operator has the same precedence as the comparison operators.
* '''Reason''': All other runtime errors in the 2xx range have appropriate exception types, so it is only natural to have an explicit type for runtime error 210 as well.
+
* '''Reason''': Bug, see [https://bugs.freepascal.org/view.php?id=35909].
* '''Remedy''': If your code previously checked an exception for the message ''Unknown runtime error 210'' you should now check for the exception class ''EObjectCheck''.
+
* '''Remedy''': Add parenthesis where needed.
  
==== Literal storage memory has been made read-only ====
+
==== Visibilities of members of generic specializations ====
 +
* '''Old behaviour''': When a generic is specialized then visibility checks are handled as if the generic was declared in the current unit.
 +
* '''New behaviour''': When a generic is specialized then visibility checks are handled according to where the generic is declared.
 +
* '''Reason''': Delphi-compatibility, but also a bug in how visibilities are supposed to work.
 +
* '''Remedy''': Rework your code to adhere to the new restrictions.
  
* '''Old behaviour''': read-only data segments were ''de facto'' not supported, and all data could be modified at runtime even if it was not intended for modification (except in some cases on Darwin). This could cause nasty side-effects, e.g the following code:
+
=== Implementation Changes ===
  
<syntaxhighlight>
+
==== Disabled default support for automatic conversions of regular arrays to dynamic arrays ====
uses sysutils;
+
* '''Old behaviour''': In FPC and ObjFPC modes, by default the compiler could automatically convert a regular array to a dynamic array.
var
+
* '''New behaviour''': By default, the compiler no longer automatically converts regular arrays to dynamic arrays in any syntax mode.
  s: ansistring;
+
* '''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 [https://bugs.freepascal.org/view.php?id=35580 TStream.Read() overloads].
begin
+
* '''Remedy''': Either change the code so it no longer assigns regular arrays to dynamic arrays, or add ''{$modeswitch arraytodynarray}''  
  s := 'ansi string';
+
* '''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)
  Writeln(AnsiStrUpper(pchar(s)));
 
  s := 'ansi string';
 
  Writeln(s);
 
end.
 
</syntaxhighlight>
 
 
 
would modify the contents of data segment and print
 
 
 
ANSI STRING
 
ANSI STRING
 
 
 
* '''New behaviour''': Data that is not intended to be modified at runtime is put into a read-only segment. This includes literal constants used in expressions and typed constants declared in {$J-} state. Any code which modifies such data (as in the above example) will now crash.
 
* '''Reason''': This is consistent with the way other compilers (including Delphi) work. Keeping data read-only as much as possible improves a program's loading speed because read-only pages can be mapped directly to the executable file. This also improves program security.
 
* '''Remedy''': is very code-dependent. In the example above, it is sufficient to call <tt>UniqueString(s)</tt> before <tt>AnsiStrUpper</tt>
 
 
 
==== ''UNICODE'' define depends on default string type instead of on target platform ====
 
* '''Old behaviour''': The compiler defined the preprocessor symbol ''UNICODE'' when targeting a Windows platforms that only has a unicode OS API (Windows CE and NativeNT).
 
* '''New behaviour''': The ''UNICODE'' define is now only set if the default string type is ''unicodestring'' (as opposed to ''shortstring'' or ''ansistring''). This happens when the new ''{$mode delphiunicode}'' or ''{$modeswitch unicodestrings}'' are active. The target platform no longer has any influence.
 
* '''Reason''': In Delphi 2009 and newer the type ''String'' is defined as ''UnicodeString'', and this can be determined by the fact that these Delphi versions also define the ''UNICODE'' symbol.
 
* '''Remedy''': Use ''{$ifdef FPC_OS_UNICODE}'' instead of ''{$ifdef UNICODE}'' to determine whether or not the OS only supports a unicode (UTF-16) API.
 
 
 
=== RTTI changes ===
 
 
 
==== RTTI for Pointers and Class References ====
 
* '''Old behavior''': Pointers and Class References had tkUnknown RTTI.
 
* '''New behavior''': Pointers now have RTTI type tkPointer, and class references have the RTTI type tkClassRef. Each now contains a reference to a type they point to.
 
* '''Reason''': Both user requests and Delphi compatibility.
 
* '''Remedy''': The TTypeKind enumeration has more members than before. Adjust any code which uses TTypeKind accordingly.
 
 
 
==== RTTI for AnsiStrings ====
 
* '''Old behavior''': AnsiString RTTI previously lacked CodePage information.
 
* '''New behavior''': A new CodePage member has been added for the tkAString type.
 
* '''Reason''': This is required for serializing/deserializing of published AnsiString properties, and is now compatible with Delphi.
 
* '''Remedy''': not known
 
 
 
==== RTTI for Arrays ====
 
* '''Old behavior''': tkArray had no member in the TTypeData record, although internally the compiler stored these members: first dimension size, first dimension element count and first dimension element type. So for a 2 dimension array element the type was array for the second dimension.
 
* '''New behavior''': tkArray now has a TArrayTypeData structure in TTypeData. It has the following members: total array size including all dimensions, total element count, last dimension element type, number of dimensions, type information for each dimension range.
 
* '''Reason''': This provides more comprehensive RTTI, and is compatible with Delphi.
 
* '''Remedy''': If your code internally used the older RTTI array information you will need to adapt it to take account of the newly provided TArrayTypeData information.
 
 
 
==== RTTI for Records ====
 
* '''Old behavior''': Records RTTI stored field Offsets as 32bit integers.
 
* '''New behavior''': Records RTTI stores field Offsets as platform-dependent integers (the same size as pointers).
 
* '''Reason''': Internally the compiler stores Offsets as platform-dependent integers. The new behaviour is Delphi-compatibile.
 
* '''Remedy''': You need to adjust your code if you used field offsets of record RTTI. This is also true if your code processes any vInitTable field within the VMT of a class.
 
 
 
==== RTTI for Procedural Variables ====
 
* '''Old behavior''': tkProcVar lacked any member in the TTypeData record and the compiler stored no information about procedural variables.
 
* '''New behavior''': tkProcVar now has a new TProcedureSignature structure in TTypeData which contains information about the procedure's calling convention, result type and parameters (where applicable).
 
* '''Reason''': User request. More informative RTTI. Delphi compatibility.
 
* '''Remedy''': not known
 
 
 
==== Usage example ====
 
<syntaxhighlight>
 
program RTTIInfo;
 
 
 
{$mode objfpc}{$H+}
 
uses
 
  typinfo;
 
  
 +
<syntaxhighlight lang="pascal">
 +
{$mode objfpc}
 
type
 
type
   CP866String = type AnsiString(866);
+
   tdynarray = array of byte;
  TProc = procedure(var A: Integer; S: String); stdcall;
 
  TColor = (red, green, blue);
 
  TArr = array[TColor,0..3] of Integer;
 
  PArr = ^TArr;
 
  
procedure DescribeProcedure(Info: PTypeInfo);
+
procedure test(var arr); overload;
const
 
  ParamFlagToStr: array[TParamFlag] of AnsiString = (
 
  'var',
 
  'const',
 
  'array',
 
  'address',
 
  'reference',
 
  'out'
 
  );
 
  CallConvToStr: array[TCallConv] of AnsiString = (
 
    'register',
 
    'cdecl',
 
    'pascal',
 
    'stdcall',
 
    'safecall',
 
    'cppdecl',
 
    'far16',
 
    'oldFPCcall',
 
    'internProc',
 
    'SysCall',
 
    'SoftFloat',
 
    'MWPascal'
 
  );
 
var
 
  Data: PTypeData;
 
  Param: PProcedureParam;
 
  ParamFlag: TParamFlag;
 
  I: Integer;
 
  Res, S, TypeName: String;
 
 
begin
 
begin
   if Info^.Kind <> tkProcedure then
+
   pbyte(arr)[0]:=1;
    Exit;
 
  Data := GetTypeData(Info);
 
  if Data^.ProcSig.CC <> ccStdCall then
 
    halt(2);
 
  if Data^.ProcSig.ResultType <> nil then
 
  begin
 
    Res := 'function ' + Info^.Name;
 
    TypeName := ': ' + Data^.ProcSig.ResultType^.Name;
 
  end
 
  else
 
  begin
 
    Res := 'procedure ' + Info^.Name;
 
    TypeName := '';
 
  end;
 
  if Data^.ProcSig.ParamCount > 0 then
 
  begin
 
    Res := Res + '(';
 
    for I := 0 to Data^.ProcSig.ParamCount - 1 do
 
    begin
 
      Param := Data^.ProcSig.GetParam(I);
 
      S := '';
 
      for ParamFlag in TParamFlags(Param^.Flags) do
 
        S := S + ParamFlagToStr[ParamFlag] + ' ';
 
      S := S + Param^.Name + ': ' + Param^.ParamType^.Name;
 
      if I > 0 then
 
        Res := Res + '; ';
 
      Res := Res + S;
 
    end;
 
    Res := Res + ')';
 
  end;
 
  Res := Res + TypeName + '; ' + CallConvToStr[Data^.ProcSig.CC] + ';';
 
  WriteLn(Res);
 
 
end;
 
end;
  
procedure DescribeAnsiString(Info: PTypeInfo);
+
procedure test(arr: tdynarray); overload;
var
 
  Data: PTypeData;
 
 
begin
 
begin
   if Info^.Kind <> tkAString then
+
   test[0]:=1;
    Exit;
 
  Data := GetTypeData(Info);
 
  if Data^.CodePage = 0 then
 
    WriteLn('AnsiString')
 
  else
 
    WriteLn('type AnsiString(',Data^.CodePage,');');
 
 
end;
 
end;
  
procedure DescribeArray(Info: PTypeInfo);
 
 
var
 
var
   Data: PTypeData;
+
   regulararray: array[1..1] of byte;
  Res: String;
 
  I: Integer;
 
 
begin
 
begin
   if Info^.Kind <> tkArray then
+
   regulararray[1]:=0;
    Exit;
+
   test(arr);
   Data := GetTypeData(Info);
+
   writeln(arr[0]); // writes 0, because it calls test(tdynarr)
   Res := 'array[';
+
end.
  for I := 0 to Data^.ArrayData.DimCount - 1 do
+
</syntaxhighlight>
  begin
+
* '''svn''': 42118
    if I > 0 then
 
      Res := Res + ', ';
 
    Res := Res + Data^.ArrayData.Dims[I]^.Name;
 
  end;
 
  Res := Res + '] of ' + Data^.ArrayData.ElType^.Name + ';';
 
  WriteLn(Res);
 
end;
 
  
procedure DescribePointer(Info: PTypeInfo);
+
==== Directive clause ''[…]'' no longer useable with modeswitch ''PrefixedAttributes'' ====
var
+
* '''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).
  Data: PTypeData;
+
* '''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:
 +
<syntaxhighlight lang="pascal">
 +
// this
 +
procedure Test; cdecl; [public,alias:'foo']
 
begin
 
begin
  if Info^.Kind <> tkPointer then
 
    Exit;
 
  Data := GetTypeData(Info);
 
  if Data^.RefType = nil then
 
    WriteLn('Pointer;')
 
  else
 
    WriteLn('^', Data^.RefType^.Name, ';');
 
 
end;
 
end;
  
 +
// becomes this
 +
procedure Test; cdecl; public; alias:'foo';
 
begin
 
begin
  DescribeProcedure(TypeInfo(TProc));
 
  DescribeAnsiString(TypeInfo(CP866String));
 
  DescribeArray(TypeInfo(TArr));
 
  DescribePointer(TypeInfo(PArr));
 
  DescribePointer(TypeInfo(Pointer));
 
end.
 
</syntaxhighlight>
 
 
=== Unit changes ===
 
 
==== DB ====
 
===== TBookmark TBookmarkstr and TDataset.Bookmark change to Delphi2009+ compatible definitions  =====
 
* '''Old behaviour''': TDataset.Bookmark was of type TBookmarkstr, TBookmarkstr=string, Tbookmark=pointer
 
* '''New behaviour''': TDataset.Bookmark is of type TBookmark, TBookmarkstr=ansistring, TBookmark=TBytes.  TBookmarkstr will trigger a deprecated warning.
 
* '''Reason''': D2009+ compatibility, where probably the fact that string became a 2-byte encoding was the trigger.
 
* '''Remedy''': Adjust typing in descendents and using code accordingly.
 
 
===== TODBCConnection (odbcconn) No longer autocommit =====
 
* '''Old behaviour''': Autocommit was enabled: Every change was committed to the database at once.
 
* '''New behaviour''': Changes must be committed explicitly using Transaction.Commit
 
* '''Reason''': Transactions are useless if everything is autocommitted: in particular; rollback is not possible.
 
* '''Remedy''': You can enable autocommit by specifying AUTOCOMMIT=1 in the params of TODBCConnection.
 
 
===== TDBF unit deprecation removed =====
 
* '''Old behaviour''': the TDBF units were marked deprecated because the original maintainer of the upstream project stopped maintenance. However, the unit remained in fcl-db and patches were still accepted.
 
* '''New behaviour''': the deprecation warning is removed. There is a new upstream project maintainer and FPC database devs support this unit again.
 
* '''Remedy''': N/A
 
* '''Target''': 2.6.4
 
 
===== TBufDataset.SaveToFile, SaveToStream: Binary Format (dfBinary) of saved data changes =====
 
* '''Old behaviour''': Record data was saved to stream just as they exist in the TBufDataset memory record buffer.
 
* '''New behaviour''': Record data are saved field by field. Each variable length field begins with a 4 byte length indicator followed by data. Fixed length fields are stored without prefixed length indicator. LoadFromFile, LoadFromStream support both formats (OLD and NEW).
 
* '''Reason''': BLOBs were not saved correctly in the OLD format: instead of BLOB data, a pointer to memory where BLOB data resided was saved.
 
* '''Remedy''': if you need the OLD behavior in saving, you must register your own DataPacketReader using RegisterDatapacketReader procedure.
 
<syntaxhighlight>
 
unit OldBinaryDatapacketReader;
 
 
{$mode objfpc}{$H+}
 
 
interface
 
 
uses
 
  Classes, SysUtils, BufDataset;
 
 
type
 
 
  { TOldFpcBinaryDatapacketReader }
 
 
  TOldFpcBinaryDatapacketReader = class(TFpcBinaryDatapacketReader)
 
  public
 
    constructor Create(AStream : TStream); override;
 
  end;
 
 
implementation
 
 
{ TOldFpcBinaryDatapacketReader }
 
 
constructor TOldFpcBinaryDatapacketReader.Create(AStream: TStream);
 
begin
 
  inherited;
 
  FVersion := 10;
 
 
end;
 
end;
 
initialization
 
  RegisterDatapacketReader(TOldFpcBinaryDatapacketReader, dfBinary);
 
end.
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
* '''svn''': 42402
  
===== TDataPacketReader class structure changes =====
+
==== Type information contains reference to attribute table ====
* '''Old behaviour''':
+
* '''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 behaviour''': reference to TCustomBufDataset is passed only once in constructor of TDataPacketReader and stored in instance TDataPacketReader.
+
* '''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''': simplify design and make it more flexible
+
* '''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 your own TDataPacketReader descendant update method signatures
 
 
 
===== TSQLScript supports :, backtick quotes and explicit COMMIT/COMMIT RETAIN =====
 
* '''Old behaviour''':  
 
** [[TSQLScript]] parsed words starting with : in SQL as if they were sqldb parameters; running the resulting statements would very likely fail, making the class unusable.
 
** With UseCommit set, once a COMMIT directive was found, CommitRetaining is run instead of Commit. This lead to problems with scripts that need a hard commit (e.g. Firebird DDL followed by DML).
 
** TSQLScript did not support backtick quotes (`), e.g. for MySQL
 
* '''New behaviour''':
 
* Parser improvement: comments starting with -- are detected as comments
 
** words starting with : are not parsed as sqldb parameters.
 
** if UseCommit is set, COMMIT WORK or COMMIT leads to Commit; the new directive COMMIT RETAIN (or no directive) leads to CommitRetaining being executed
 
** TSQLScript supports backtick quotes (`), e.g. for MySQL
 
* '''Reason''': usability, compatibility with scripts generated by 3rd party packages.
 
* '''Remedy''':
 
** if your code depended on : parameter parsing, you could use a TSQLEventScript class and manipulate the SQL.  
 
** commit behaviour: check your scripts for any unexpected COMMIT RETAIN statements.
 
 
 
===== TMySQLxxConnection (mysqlconn.inc) VARCHAR columns are always mapped to TStringFields =====
 
* '''Old behaviour''': varchar columns with length > 8192 (dsMaxStringSize) were re-mapped to TMemoFields
 
* '''New behaviour''': varchar columns are always mapped to TStringFields
 
* '''Reason''': Honour server definition and map column data types as reported by server
 
* '''Remedy''': If you use varchar with length > 8192 and you have field definitions stored in lfm, update them.
 
 
 
===== TSQLite3Connection INTEGER PRIMARY KEY columns are mapped to TAutoIncFields =====
 
* '''Old behaviour''': INTEGER columns, which are also PRIMARY KEY were mapped to TIntegerField
 
* '''New behaviour''': INTEGER columns, which are also PRIMARY KEY are now mapped to TAutoIncField
 
* '''Reason''': Tables with INTEGER columns, which are also PRIMARY KEY are in SQLite alias for ROWID. And ROWID columns have autoincrement capability. For more details see: http://www.sqlite.org/lang_createtable.html#rowid and http://www.sqlite.org/autoinc.html
 
 
* '''Remedy''':
 
* '''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 outside of that range
 +
* '''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 would be expected, because  $ffffffff was interpreted as "-1".
 +
* '''Remedy''': Add Longint typecasts to values outside the valid range of a Longint.
  
==== FileNameCaseSensitive and FileNameCasePreserving in unit System ====
+
==== Comp as a type rename of Int64 instead of an alias ====
* '''Old behaviour''': There was only one constant (FileNameCaseSensitive) which signalized behaviour of the respective target platform with regard to the case in filenames. This was often set to true also on platforms not really treating filenames in case sensitive manner (e.g. Win32 and Win64).
+
* '''Old behavior''': On non-x86 as well as Win64 the Comp type is declared as an alias to Int64 (''Comp = Int64'').
* '''New behaviour''': FileNameCaseSensitive is set to true only on platforms which really treat filenames in case sensitive manner and FileNameCasePreserving constant is added to unit system of all platforms to signalize whether the case in filenames supplied when creating or renaming them is preserved or not. This might possibly break existing user code relying on the previous (sometimes incorrect) value of FileNameCaseSensitive.
+
* '''New behavior''': On non-x86 as well as Win64 the Comp type is declared as a type rename of Int64 (''Comp = type Int64'').
* '''Reason''': In reality, there are two distinct types of behaviour. If a platform is case sensitive, searching for file "a" will never result in finding file "A" whereas case insensitive platform will happily return "A" if such a file is found on the disk. If a platform is case preserving, it will store file "a" as "a" on disk whereas case non-preserving platform may convert the filenames to uppercase before storing them on disk (i.e. file "a" is in reality stored as "A"). Case non-preserving platforms are never case sensitive, but case preserving platforms may or may not be case sensitive at the same time.
+
* '''Reason''':
* '''Remedy''': Review your existing code using FileNameCaseSensitive, check which of the two properties described above fit the particular purpose in your case and change to FileNameCasePreserving where appropriate.
+
** This allows overloads of ''Comp'' and ''Int64'' methods/functions
 +
** This allows to better detect properties of type ''Comp''
 +
** Compatibility with Delphi for Win64 which applied the same reasoning
 +
* '''Remedy''': If you relied on ''Comp'' being able to be passed to ''Int64'' variables/parameters either include typecasts or add overloads for ''Comp''.
 +
* '''svn''': 43775
  
==== Some longtime deprecated functions in unit Unix have been removed. ====
+
==== Routines that only differ in result type ====
* '''Old behaviour''': Unix.(f)statfs, Unix.shell and Unix.fsync symbols existed in unit Unix
+
* '''Old behaviour:''' It was possible to declare routines (functions/procedures/methods) that only differ in their result type.
* '''New behaviour''': Unix.(f)statfs, Unix.shell and Unix.fsync were removed
+
* '''New behaviour:''' It is no longer possible to declare routines that only differ in their result type.
* '''Reason''': These were helper functions and leftovers from the 1.0.x->2.0.0 conversion, deprecated since 2007. Shell had non standarized conventions
+
* '''Reason:''' It makes no sense to allow this as there are situations where the compiler will not be able to determine which function to call (e.g. a simple call to a function ''Foo'' without using the result).
* '''Remedy''': All but shell: use the same functions with an "fp" prefix. Shell: use fpsystem. If you checked the return value for other values than -1, a modification of the error checking might be necessary. Refer to your *nix documention, or have a look at the transformfpsystemtoshell function in tests/util/redir.pp in the FPC sources to see what a quick fix looks like.
+
* '''Remedy:''' Correctly declare overloads.
 +
* '''Notes:'''
 +
** As the JVM allows covariant interface implementations such overloads are still allowed inside classes for the JVM target.
 +
** Operator overloads (especially assignment operators) that only differ in result type are still allowed.
 +
* '''svn:''' 45973
  
==== statfs has been renamed to fpstatfs ====
+
==== Open Strings mode enabled by default in mode Delphi ====
* '''Old behaviour''': One overload of fpstatfs was not renamed from statfs to fpstatfs (around 2.4.0)
+
* '''Old behaviour:''' The Open Strings feature (directive ''$OpenStrings'' or ''$P'') was not enabled in mode Delphi.
* '''New behaviour''': The function has been renamed.
+
* '''New behaviour:''' The Open Strings feature (directive ''$OpenStrings'' or ''$P'') is enabled in mode Delphi.
* '''Reason''': Should have been done in 2.4.0 to begin with, but was postponed several times to coincide with a major version change.  
+
* '''Reason:''' Delphi compatibility.
* '''Remedy''': Use fpstatfs
+
* '''Remedy:''' If you have assembly routines with a ''var'' parameter of type ''ShortString'' then you also need to handle the hidden ''High'' parameter that is added for the Open String or you need to disable Open Strings for that routine.
 +
* '''git:''' [https://gitlab.com/freepascal.org/fpc/source/-/commit/188cac3bc6dc666167aacf47fedff1a81d378137 188cac3b]
  
==== RTLeventsync has been removed ====
+
=== Unit changes ===
* '''Old behaviour''': The thread manager record contained an ''rtleventsync'' field, and the RTL had an ''RTLeventsync'' routine. No functionality for this routine was implemented in the FPC-supplied thread manager for any platform.
 
* '''New behaviour''': The field and routine have been removed.
 
* '''Reason''': The functionality was not available on any platform by default, and we're not aware of any third party thread manager that implemented them or third party code that relied on it. Additionally, the routine was documented as "Obsolete. Don't use.", without any explanation of what it was supposed to do.
 
* '''Remedy''': Remove any such calls from your code.
 
  
==== FPCanvas Strikethough property spelling fixed to StrikeThrough ====
+
==== System - TVariantManager ====
* '''Old behaviour''': Fonts had a Striketrough property which is a typo.
 
* '''New behaviour''': The property has been changed to Strikethrough.
 
* '''Reason''': Spelling fix.
 
* '''Remedy''': Please rename property calls in your code. FPC 2.6.2 contains both versions so there is a window for adaptation.
 
* '''Target''': 2.6.4
 
  
==== TVersionInfo (fileinfo unit) re-implemented in a platform independent way ====
+
* '''Old behaviour:''' ''TVariantManager.olevarfromint'' has a ''source'' parameter of type ''LongInt''.
* '''Old behaviour''': GetVersionSetting method would read file information.
+
* '''New behaviour:''' ''TVariantManager.olevarfromint'' has a ''source'' parameter of type ''Int64''.
* '''New behaviour''': The ReadFileInfo call will read the information. The global GetProgramVersion call will extract the program major/minor/revision/build version in 1 single call.
+
* '''Reason for change:''' 64-bit values couldn't be correctly converted to an OleVariant.
* '''Reason''': The unit now uses FPC resources on all platforms, and can now be used to read external resources.
+
* '''Remedy:''' If you implemented your own variant manager then adjust the method signature and handle the range parameter accordingly.
* '''Remedy''': Use the ReadFileInfo call to get the version information. Add relevant units for desired resource support to your uses clause; e.g. if you need to read Windows .exe file info, add winpeimagereader
+
* '''svn:''' 41570
  
==== shlobj symbols removed from unit Windows ====  
+
==== System - buffering of output to text files ====
* '''Old behaviour''': When unit windows was split between the windows and shlobj units, not all shlobj symbols were removed from Windows.
 
* '''New behaviour''':
 
** Now: the symbols are marked deprecated in the windows unit.
 
** Next major version: shlobj symbols will be removed from the windows unit. Code relying on that will fail to compile if it doesn't import shlobj.
 
* '''Reason''': shlobj and windows versions were not compatible and lead to errors.
 
* '''Remedy''': put shlobj in your uses, if not there already.
 
* '''Target''': 2.6.4
 
  
==== StrUtils RomanToInt implementation ====
+
* '''Old behaviour:''' Buffering was disabled only for output to text files associated with character devices (Linux, BSD targets, OS/2), or for output to Input, Output and StdErr regardless of their possible redirection (Win32/Win64, AIX, Haiku, BeOS, Solaris).
* '''Old behaviour''': Providing an invalid input to RomanToInt would return 0.
+
* '''New behaviour:''' Buffering is disabled for output to text files associated with character devices, pipes and sockets (the latter only if the particular target supports accessing sockets as files - Unix targets).
* '''New behaviour''': Providing an invalid input to RomanToInt will raise an EConvert error.
+
* '''Reason for change:''' The same behaviour should be ensured on all supported targets whenever possible. Output to pipes and sockets should be performed immediately, equally to output to character devices (typically console) - in case of console users may be waiting for the output, in case of pipes and sockets some other program is waiting for this output and buffering is not appropriate. Seeking is not attempted in SeekEof implementation for files associated with character devices, pipes and sockets, because these files are usually not seekable anyway (instead, reading is performed until the end of the input stream is reached).
* '''Reason''': What constitutes "Invalid input" was very arbitrary: only invalid characters constituted an error. Right characters in wrong places would be erroneously translated. Now the implementation has the three usual implementations TryRomanToInt, RomanToIntDef and RomanToInt
+
* '''Remedy:''' Buffering of a particular file may be controlled programmatically / changed from the default behaviour if necessary. In particular, perform TextRec(YourTextFile).FlushFunc:=nil immediately after opening the text file (i.e. after calling Rewrite or after starting the program in case of Input, Output and StdErr) and before performing any output to this text to enable buffering using the default buffer, or TextRec(YourTextFile).FlushFunc:=TextRec(YourTextFile).FileWriteFunc to disable buffering.
* '''Remedy''': Use RomanToIntDef. The Default value used in case of error is declared with default 0, making the signature and behaviour equivalent to the old function.
+
* '''svn:''' 46863
* '''Target''': 2.6.4
 
  
==== process OnForkEvent implementation ====
+
==== System - type returned by BasicEventCreate on Windows ====
* '''Old behaviour''': Signature was a simple procedure.
 
* '''New behaviour''': TNotifyEvent -compatible signature for the call.
 
* '''Reason''': It was impossible to know the TProcess instance for which the fork was called, and hence impossible to parametrize the procedure.
 
* '''Remedy''': Change the signature of your callback to match a TNotifyEvent
 
  
==== Extention -> Extension typo fix ====
+
* '''Old behaviour:''' BasicEventCreate returns a pointer to a record which contains the Windows Event handle as well as the last error code after a failed wait. This record was however only provided in the implementation section of the  ''System'' unit.
* '''Old behaviour''': The incorrect term Extention (typo) was used in the interface of several units: fpimage, sndfile.
+
* '''New behaviour:''' BasicEventCreate returns solely the Windows Event handle.
* '''New behaviour''': The correct term Extension is now used.
+
* '''Reason for change:''' This way the returned handle can be directly used in the Windows ''Wait*''-functions which is especially apparent in ''TEventObject.Handle''.
* '''Reason''': Why have code with incorrect English?
+
* '''Remedy:''' If you need the last error code after a failed wait, use ''GetLastOSError'' instead.
* '''Remedy''': Change extention to extension.
+
* '''svn:''' 49068
  
==== SysUtils: File names starting with a period are not considered to be extensions ====
+
==== System - Ref. count of strings ====
* '''Old behaviour''': File names that start with a period were considered to only have an extension and no base file name by <code>ExtractFileExt()</code> and <code>ChangeFileExt()</code>
 
* '''New behaviour''': By default, the portion of the filename starting with the period up till the next period (if any) or end of the file name is now considered to be the file name, and the rest is considered by the extension. Note that this behaviour is '''not''' Delphi-compatible.
 
* '''Reason''': Change behaviour to match file system/OS conventions.
 
* '''Remedy''': There is a new a variable <code>FirstDotAtFileNameStartIsExtension</code>. By default, it is set to ''false'', which corresponds to the new behaviour. If it is set to ''true'', the aforementioned routines revert to the old behaviour.
 
==== System: Error messages are now written to stderr ====
 
* '''Old behaviour''': On error, the binaries halted and wrote an error message to standard output.
 
* '''New behaviour''': On error, the binaries halt and write an error message to standard error .
 
* '''Reason''': Change behaviour to match OS conventions. Diagnostic output should be written to standard error.
 
* '''Remedy''': A system unit variable WriteErrorsToStdErr can be set to 'False' and then the output is written to standard output, as it was.
 
  
==== TZipper: writes zip files with zip standard / instead of \ directory separators ====
+
* '''Old behaviour:''' Reference counter of strings was a ''SizeInt''
* '''Old behaviour''': on Windows (only), TZipper would write \ to the zip file when paths were used. This does not conform to the zip standard though many utilities would accept this. However, it is not according to the standard and leads to problems with e.g. LibreOffice reading .xlsx files generated by fpspreadsheet.
+
* '''New behaviour:'''  Reference counter of strings is now a ''Longint'' on 64 Bit platforms and ''SizeInt'' on all other platforms.
* '''New behaviour''': TZipper writes / when paths are used; it still accepts \ for reading on Windows. Note: on Windows, TZipper still accepts / as path separator when reading zip files for compatibility with buggy third party code.
+
* '''Reason for change:''' Better alignment of strings
* '''Reason''': standards compliance, interoperability.
+
* '''Remedy:''' Call ''System.StringRefCount'' instead of trying to access the ref. count field by pointer operations or other tricks.
* '''Remedy''': if you need to interoperate with 3rd party tools that require zip files with \, please copy all code in \packages\paszlib\src and edit procedures SetArchiveFileName, SetDiskFileName
+
* '''git:''' [https://gitlab.com/freepascal.org/fpc/source/-/commit/ee10850a5793b69b19dc82b9c28342bdd0018f2e ee10850a57]
  
=== Language Changes ===
+
==== System.UITypes - function TRectF.Union changed to procedure ====
  
==== AnsiStrings are now codepage-aware ====
+
* '''Old behaviour:''' ''function TRectF.Union(const r: TRectF): TRectF;''
* '''Old behaviour''': The codepage of an ''AnsiString'' was always be assumed to be the default system (single byte) code page. The predefined ''Utf8String'' type was just an alias for ''AnisString'' and did not behave differently in any way.
+
* '''New behaviour:''' ''procedure TRectF.Union(const r: TRectF);''
* '''New behaviour''': Every ''AnsiString'' constant or variable now also has an associated code page, which governs how its data is interpreted. The predefined ''Utf8String'' type is now tagged with the UTF-8 codepage identifier.
+
* '''Reason for change:''' Delphi compatibility and also compatibility with TRect.Union
* '''Reason''': Delphi 2009+ compatibility.
+
* '''Remedy:''' Call ''class function TRectF.Union'' instead.
* '''Remedy''': This new feature generally works transparently, but there are some caveats:
+
* '''git:''' [https://gitlab.com/freepascal.org/fpc/source/-/commit/5109f0ba444c85d2577023ce5fbdc2ddffc267c8 5109f0ba]
** Avoid using ''AnsiString'' variables to store data not encoded using the ''DefaultSystemCodePage'' encoding without also setting the corresponding code page (such as currently done in Lazarus). For example, assume an ''AnsiString'' with a [[FPC_Unicode_support#Dynamic_code_page|dynamic code page]] different from ''CP_UTF8'' (e.g. [[FPC_Unicode_support#Code_page_identifiers|CP_ACP]]) contains UTF-8 data. If it is then converted to a different code page, e.g. because it's passed to a routine expecting a ''UnicodeString'' or ''Utf8String'' parameter, then the UTF-8 data in the string will be "converted" from CP_ACP to UTF-8, thereby corrupting the string data (if CP_ACP is different from UTF-8).
 
** Routines that are declared with a plain ''AnsiString'' parameter will cause passed custom code page strings to be converted to ''DefaultSystemCodePage'', possibly resulting in data loss. We have [[FPC_Unicode_support#RTL_changes|a list of RTL routines]] that have been updated to correctly handle strings encoded in any code page.
 
* '''More information''': [[FPC_Unicode_support|FPC Unicode support]]
 
  
==== Variant overload preference for string types ====
+
==== 64-bit values in OleVariant ====
* '''Old behaviour''': Preference for string types was (from better to worse): ShortString, AnsiString, WideString, UnicodeString
 
* '''New behaviour''': Preference for string types now (from better to worse): WideString, UnicodeString, AnsiString, ShortString
 
* '''Reason''': Unicode characters and codepage information will not be lost during the conversion; unicode Delphi compatibility.
 
* '''Remedy''': Use explicit conversion (e.g. ShortString(V)) if it is needed to pass variant to routine with a particular string type argument.
 
==== Variant conversion preference for widechar ====
 
* '''Old behaviour''': If a ''widechar'' was passed to a ''variant'' parameter, it would be wrapped as a ''word'' (D7 compatible).
 
* '''New behaviour''': A ''widechar'' passed to a ''variant'' parameter is now convert it to a unicodestring (D2009+ compatible).
 
* '''Reason''': Newer Delphi version compatibility.
 
* '''Remedy''': Use explicit conversion (e.g. integer(V)) if needed. We decided against differentiating this behaviour between ''{$mode delphi}'' and ''{$mode delphiunicode}'' because the compatibility advantage does not outweigh implementation complexity.
 
  
==== Default values in implementation but not in interface/forward declaration ====
+
* '''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.
* '''Old behaviour''': The implementation of a routine could declare default values even if the interface declaration did not have any.
+
* '''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.
* '''New behaviour''': Default values, if any, must be specified in the interface. They can be repeated in the implementation, but that is not required (just like it was not in the past).
+
* '''Reason for change:''' 64-bit values weren't correctly represented. This change is also Delphi compatible.
* '''Reason''': Default parameters specified only in the implementation are not, and cannot, be propagated to the interface since a unit's interface can be used before the implementation has been parsed (see http://bugs.freepascal.org/view.php?id=19434), Delphi compatibility.
+
* '''Remedy:''' Ensure that you handle 64-bit values correctly when using OleVariant.
* '''Remedy''': Always specify default parameter values (also) in the interface/forward declaration of a routine.
+
* '''svn:''' 41571
  
==== Default values are now properly typechecked ====
+
==== Classes TCollection.Move ====
* '''Old behaviour''': The compiler did not detect default values for parameters of which the type did not in any way correspond to the parameter type.  
+
* '''Old behaviour:''' If a TCollection.Descendant called Move() this would invoke System.Move.
* '''New behaviour''': The compiler now properly checks whether the type of the constant matches the parameter's type when parsing default values.
+
* '''New behaviour:''' If a TCollection.Descendant called Move() this invokes TCollection.Move.
* '''Reason''': Proper type checking is one of the fundamental properties of the Pascal language; Delphi compatibility.
+
* '''Reason for change:''' New feature in TCollection: move, for consistency with other classes.
* '''Remedy''': Add a typecast around default values that now result in compiler errors, or correct the type of such parameters.
+
* '''Remedy:''' prepend the Move() call with the system unit name: System.move().
 +
* '''svn:''' 41795
  
==== Recursive parameterless function calls in MacPas mode ====
+
==== Math Min/MaxSingle/Double ====
* '''Old behaviour''': When using the name of a function inside its own body on the right hand side of an expression, the compiler treated this as a read of the last value assigned to the function result in MacPas mode.
+
* '''Old behaviour:''' MinSingle/MaxSingle/MinDouble/MaxDouble were set to a small/big value close to the smallest/biggest possible value.
* '''New behaviour''': The compiler will now treat such occurrences of the function name as recursive function calls in MacPas mode.
+
* '''New behaviour:''' The constants represent now the smallest/biggest positive normal numbers.
* '''Reason''': Compatibility with Mac Pascal compilers.
+
* '''Reason for change:''' Consistency (this is also Delphi compatibility), see https://gitlab.com/freepascal.org/fpc/source/-/issues/36870.
* '''Remedy''': If you wish to read the current function result value, compile the code with ''{$modeswitch result}'', after which you can use the ''result'' alias for that value. Note that the use of this mode switch can also result in [[User_Changes_2.6.0#Implicit_.22result.22_variable_in_MacPas_mode|different behaviour]] compared to traditional Mac Pascal compilers.
+
* '''Remedy:''' If the code really depends on the old values, rename them and use them as renamed.
 +
* '''svn:''' 44714
  
==== "''strict protected''" visibility modifier ====
+
==== Random generator ====
* '''Old behaviour''': ''strict protected'' did not correctly limit the visibility of symbols declared in different units.
+
* '''Old behaviour:''' FPC uses a Mersenne twister generate random numbers
* '''New behaviour''': ''strict protected'' symbols can now only be accessed from descendent classes, regardless of where they are defined.
+
* '''New behaviour:''' Now it uses Xoshiro128**
* '''Reason''': Fix behaviour to conform to specification/documentation, Delphi compatibility.
+
* '''Reason for change:''' Xoshiro128** is faster, has a much smaller memory footprint and generates better random numbers.
* '''Remedy''': Use ''protected'' or ''public'' if less strict accessibility checks are desired.
+
* '''Remedy:''' When using a certain randseed, another random sequence is generated, but as the PRNG is considered as an implementation detail, this does not hurt.
 +
* '''git:''' 91cf1774
  
==== Support for type helpers added ====
+
==== Types.TPointF.operator * ====
* '''Old behaviour''': In modes ''ObjFPC'' and ''MacPas'' it was possible to declare a unique type of a type ''helper''.
+
* '''Old behaviour:''' for <code>a, b: TPointF</code>, <code>a * b</code> is a synonym for <code>a.DotProduct(b)</code>: it returns a <code>single</code>, scalar product of two input vectors.
* '''New behaviour''': The compiler now interprets the keyword ''helper'' as a helper type if it immediately follows the ''type'' keyword (but only if the mode is ''ObjFPC'' or ''MacPas'' or the mode switch ''Class'' is set).
+
* '''New behaviour:''' <code>a * b</code> does a component-wise multiplication and returns <code>TPointF</code>.
* '''Example''':
+
* '''Reason for change''': Virtually all technologies that have a notion of vectors use <code>*</code> for component-wise multiplication. Delphi with its <code>System.Types</code> is among these technologies.
<syntaxhighlight>
+
* '''Remedy:''' Use newly-introduced <code>a ** b</code>, or <code>a.DotProduct(b)</code> if you need Delphi compatibility.
{$mode objfpc}
+
* '''git:''' [https://gitlab.com/freepascal.org/fpc/source/-/commit/f1e391fb415239d926c4f23babe812e67824ef95 f1e391fb]
type
 
  helper = LongInt;
 
  
  otherhelper = type helper;
+
==== CocoaAll ====
</syntaxhighlight>
+
===== CoreImage Framework Linking =====
The above code will no longer compile.
+
* '''Old behaviour''': Starting with FPC 3.2.0, the ''CocoaAll'' unit linked caused the ''CoreImage'' framework to be linked.
* '''Reason''': ''type helper'' is a more logical way to declare helpers for primitive types than Delphi's ''record helper'' is.
+
* '''New behaviour''': The ''CocoaAll'' unit no longer causes the ''CoreImage'' framework to be linked.
* '''Remedy''': Escape the keyword ''helper'' using a ''&''. E.g.:
+
* '''Reason for change''': The ''CoreImage'' framework is not available on OS X 10.10 and earlier (it's part of ''QuartzCore'' there, and does not exist at all on some even older versions).
<syntaxhighlight>
+
* '''Remedy''': If you use functionality that is only available as part of the separate ''CoreImage'' framework, explicitly link it in your program using the ''{$linkframework CoreImage}'' directive.
{$mode objfpc}
+
* '''svn''': 45767
type
 
  helper = LongInt;
 
  
  otherhelper = type &helper;
+
==== DB ====
</syntaxhighlight>
+
===== TMSSQLConnection uses TDS protocol version 7.3 (MS SQL Server 2008) =====
 
+
* '''Old behaviour:''' TMSSQLConnection used TDS protocol version 7.0 (MS SQL Server 2000).
==== "''strict protected''" and "''protected''" visibility modifier in extended records ====
+
* '''New behaviour:''' TMSSQLConnection uses TDS protocol version 7.3 (MS SQL Server 2008).
* '''Old behaviour''': ''strict protected'' and ''protected'' could be used used in extended records.
+
* '''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.
* '''New behaviour''': ''strict protected'' and ''protected'' are no longer allowed in extended records.
+
* '''svn''': 42737
* '''Reason''': The only difference between ''(strict) protected'' and ''(strict) private'' is that the former allows you to access members of a parent class or object. As records don't support inheritence it makes no sense to support ''(strict) protected'' in them. This is also Delphi-compatible.
 
* '''Remedy''': Use ''private'' instead of ''protected'' and ''strict private'' instead of ''strict protected''.
 
 
 
==== "''static''" directive on non-class methods ====
 
* '''Old behaviour''': It was possible to use the ''static'' on normal, non-''class'' methods
 
* '''New behaviour''': The compiler now generates an error if ''static'' is used on normal, non-''class'' methods (except in ''object'' types)
 
* '''Reason''': It is only correct to leave out the ''Self'' parameter if it is a class method. This is also Delphi compatible.
 
* '''Remedy''': Prepend the ''class'' keyword to the method.
 
 
 
==== "''static''" directive on class operators ====
 
* '''Old behaviour''': It was possible to use the ''static'' on class operators.
 
* '''New behaviour''': The compiler now generates an error if ''static'' is used on class operators.
 
* '''Reason''': Class operators are by definition static, thus the ''static'' would be redundant. This is also Delphi compatible.
 
* '''Remedy''': Remove the ''static'' keyword from class operators.
 
 
 
====Classes implementing forward-declared interfaces====
 
* '''Old behaviour''': It was possible to declare classes as implementing a forward-declared interface.
 
* '''New behaviour''': Classes can no longer implement forward-declared interfaces.
 
* '''Reason''': This occasionally [http://bugs.freepascal.org/view.php?id=24184 caused crashes], the compiler did not check in such a case whether the class actually implemented the methods of that interface. Recent versions of Delphi also reject such constructs.
 
* '''Remedy''': If there is a cyclic dependency between a class and an interface, use a forward declaration for the class instead.
 
 
 
====Using the function name as alias for loading its current result value in MacPas mode====
 
* '''Old behaviour''': Inside a function the name of the function could be used on the right hand side (RHS) of an expression in order to refer to the current value of the function result.
 
* '''New behaviour''': Using the name of a function on the RHS of an expression inside that function's body now always results in a recursive function call.
 
* '''Reason''': The old behaviour existed because under '''some''' circumstances CodeWarrior behaved that way. Under other circumstances [http://bugs.freepascal.org/view.php?id=22344 it however behaves according to the new rule] and there appears to be no definition available of when it does what. Since it is easier to fix a compilation error than to find out where an intended recursive function call is not doing anything, we opted to change the behaviour.
 
* '''Remedy''': Either use a temporary local variable to hold the function result if you want to reuse it on the RHS of other expressions, or add '''{$modeswitch result}''' and use the '''result''' pseudo-variable as an alias for the function result.
 
 
 
==== nostackframe forbidden for Pascal subroutines ====
 
* '''Old behaviour''': The nostackframe directive could be applied to all types of subroutines.
 
* '''New behaviour''': The nostackframe directive is allowed only for pure assembler subroutines,
 
* '''Reason''': Depending on the architecture, ABI and code of the subroutine, nostackframe might have worked or caused random crashes. This was unpredictable and makes no sense.
 
* '''Remedy''': Remove the nostackframe from Pascal subroutines. In any case, if the compiler can omit the stack frame, it will do so.
 
 
 
====Conversion preference of pansichar to various string types====
 
* '''Old behaviour''': In {$h-} mode, the compiler preferred ''pansichar''->''shortstring'' to ''pchar''->''ansistring'' conversions, and gave ''pansichar''->''ansistring'' and ''pchar''->''unicodestring'' the same conversion preference.
 
* '''New behaviour''': The compiler now always prefers ''pansichar''->''ansistring'' to ''pansichar''->''shortstring'', and also prefers ''pansichar''->''ansistring'' to ''pansichar''->''unicodestring'' (which it in turn prefers to ''pansichar''->''shortstring'').
 
* '''Reason''': Prevent truncation of long pchars, make it easier to add unicodestring overloads to the RTL without causing ''can't decide which overloaded function to call'' errors when using pchars, Delphi compatibility.
 
* '''Remedy''': Use ''strpas()'' to explicitly truncate pchars to shortstrings if desired.
 
 
 
==== Comparative operators can have any result type ====
 
* '''Old behaviour''': Overloaded comparative operators could only have a ''Boolean'' result type.
 
* '''New behaviour''': Overloaded comparative operators can have any result type.
 
* '''Reason''': The result type is checked by the regular type checking mechanism. For example, overloaded comparative operators that return non-Boolean results cannot be used in IF, WHILE or UNTIL expressions, but it is still possible to use them in other situations. This is also Delphi compatible.
 
* '''Example''':
 
<syntaxhighlight>
 
SQLResult := Database.Query(
 
  Select(
 
    [ PersonsTable.FirstName, PersonsTable.LastName ],
 
    [ PersonsTable ],
 
    [
 
      PersonsTable.Country = 'NL',
 
      PersonsTable.Age >= 25
 
    ]
 
  )
 
);
 
</syntaxhighlight>
 
* '''Remedy''': Not applicable.
 
 
 
==== True and False are not keywords anymore ====
 
* '''Old behaviour''': True and False were keywords and as a result it was not possible to use them as identifiers.
 
* '''New behaviour''': True and False are now predefined constants in the system unit's scope and can be used as identifiers.
 
* '''Example''':
 
<syntaxhighlight>
 
const
 
  False = 0;
 
  True = 1;
 
</syntaxhighlight>
 
* '''Reason''': Compatibility with other Pascal compilers.
 
* '''Remedy''': Not applicable.
 
 
 
==== For in loop variable cannot be assigned to anymore ====
 
* '''Old behaviour''': Inside a ''for X in Y'' loop it was possible to assign a value to X. This was different from the ''for X:=A to B'' loop, where assigning to the loop variable X was not allowed.
 
* '''New behaviour''': The variable X of a ''for X in Y'' loop cannot be changed.
 
* '''Reason''': Compatibility with for ''X:=A to B'' loop.
 
* '''Remedy''': Use a temporary variable instead.
 
 
 
==== Casting integer variables to floating point ====
 
* '''Old behaviour''': Explicitly typecasting an integer variable to a floating point type of the same size caused the bit pattern of the integer to be reinterpreted as a floating point value.
 
* '''New behaviour''': Such explicit typecasts now result in a conversion of the integer value to an equal floating point value (to the extent that the floating point type can represent the integer value)..
 
* '''Example''': The following program now prints twice " 1.3890388970000000E+009", while previously the first writeln printed " 6.86276399744918E-315"
 
<syntaxhighlight>
 
var
 
  i: int64;
 
begin
 
  i:=1389038897;
 
  writeln(Double(i))
 
  writeln(Double(1389038897))
 
end.
 
</syntaxhighlight>
 
* '''Reason''': Consistency with the behaviour of a compile-time integer to floating point conversions, as demonstrated by the above example.
 
* '''Remedy''': Add an intermediate typecast to a record type to reinterpret the actual bit pattern.
 
==== Visibility of generic type parameters ====
 
* '''Old behaviour''': Type parameters of generics had ''public'' visibility.
 
* '''New behaviour''': Type parameters of generics now have ''strict private'' visibility.
 
* '''Reason''': With the previous visibility it was possible to create code that leads to infinite loops during compilation or other hard to debug errors. In addition there is no real possibility to work around this issue (for an example see [http://bugs.freepascal.org/view.php?id=25917 this] bug report). Also the fix is Delphi compatible.
 
* '''Remedy''': Declare a type alias for the type parameter with the desired visibility.
 
* '''Example''': In the following example ''T'' is declared as ''strict private'', while ''TAlias'' is declared as ''public'' and thus can be used as before the change.
 
<syntaxhighlight>
 
type
 
  generic TTest<T> = class
 
  public type
 
    TAlias = T;
 
  end;
 
</syntaxhighlight>
 
 
 
==== Parsing of ''specialize'' is changed ====
 
* '''Old behaviour''': ''specialize'' was used to initialize a specialization and was followed by a type name that might contain a unit name and parent types.
 
* '''New behaviour''': ''specialize'' is now considered part of the specialized type, just as ''generic'' is. This means that unit names and parent types need to be used before the part containing the ''specialize''.
 
* '''Reason''': This allows for a more logical usage of ''specialize'' in context with nested types (especially if multiple specializations are involved) and more importantly generic functions and methods.
 
* '''Remedy''': Put the ''specialize'' directly in front of the type which needs to be specialized.
 
 
 
== Unix platforms ==
 
 
 
=== cthreads: critical sections and recursive mutex support ===
 
* '''Old behaviour''': If the ''cthreads'' unit thread manager was used on a platform without recursive mutex support, critical sections were non-reentrant.
 
* '''New behaviour''': Initialising a critical section under the above circumstances will now result in a run time error.
 
* '''Reason''': One of the basic properties of (Delphi/Windows-compatible) critical sections is that they are reentrant, and that is how they are generally used in Pascal code.
 
* '''Remedy''': Use an RTLEvent instead if reentrancy is not required.
 
 
 
 
 
== Darwin/i386 and iPhoneSim/i386 ==
 
 
 
=== Location of certain function result types ===
 
* '''Old behaviour''': Small records and method pointers were always returned according to the official ABI.
 
* '''New behaviour''': When a calling convention other than ''cdecl'', ''cppdecl'' or ''mwpascal'' is used, the same convention as on other platforms is now used.
 
* '''Reason''': Better compatibility with assembler code written for other platforms.
 
* '''Remedy''': Update your assembler code, or better: if possible, convert it to Pascal.
 
 
 
== All Darwin/Mac OS X/iOS ==
 
===MacOSAll unit: changed parameter and opaque types===
 
 
 
* '''Change''': The headers have been updated to the Mac OS X 10.8 SDK, and in this process a number of signatures have been changed/corrected, and several opaque types have been changed from ^SInt32 into pointers to different/incompatible empty records.
 
* '''Reason''': The reasons for the signature changes are detailed below. The opaque types have been made incompatible so that the compiler can give error messages when trying to use one opaque type instead of another (e.g., in the past the compiler did not complain when passing a ControlRef to a routine that expected a WindowPtr).
 
* '''Remedy''': Adjust your code to conform to the new signatures. Regarding the opaque types, that means that these types are no longer assignment-compatible. Some of the more prominent ones that may affect existing, correct, code are HIObject and ControlRef=HIViewRef. This may require adding typecasts to keep code compiling (the same typecasts are required in C)
 
* '''Changes:''' (apart from the opaque type changes)
 
** CGGLContextCreate : fixed first parameter (was "var", now is value parameter)
 
** CFHostGetAddressing: var hasBeenResolved: boolean -> booleanptr because can be nil
 
** CFHostGetNames: var hasBeenResolved: boolean -> booleanptr because can be nil
 
** ColorSyncIterateInstalledProfiles: var seed: UInt32 -> UInt32Ptr because can be nil
 
** AudioStreamGetPropertyInfo: outSize and outWritable changed to pointer because can be nil
 
** cblas (several var-parametes changed to pointers because they represent arrays):
 
*** cblas_sswap, cblas_dswap: X, Y
 
*** cblas_scopy, cblas_dcopy: Y
 
*** cblas_saxpy, cblas_daxpy: Y
 
*** catlas_saxpby, catlas_daxpby: Y
 
*** catlas_sset, catlas_dset: X
 
*** cblas_sscal, cblas_dscal: X
 
*** cblas_sgemv, cblas_dgemv: X
 
*** cblas_strmv, cblas_dtrmv: X
 
*** cblas_stbmv, cblas_dtbmv: X
 
*** cblas_stpmv, cblas_dtpmv: Ap, X
 
*** cblas_strsv, cblas_dtrsv: X
 
*** cblas_stbsv, cblas_dtbsv: X
 
*** cblas_stpsv, cblas_dtpsv: Ap, X
 
*** cblas_ssymv, cblas_dsymv: X
 
*** cblas_ssbmv, cblas_dsbmv: Y
 
*** cblas_sspmv, cblas_dspmv: Ap, Y
 
*** cblas_sger, cblas_dger: A
 
*** cblas_ssyr, cblas_dsyr: A
 
*** cblas_sspr, cblas_dspr: Ap
 
*** cblas_ssyr2, cblas_dsyr2: A
 
*** cblas_sspr2, cblas_dspr2: A
 
*** cblas_sgemm, cblas_sgemm: C
 
*** cblas_ssymm, cblas_Dsymm: C
 
*** cblas_ssyrk, cblas_dsyrk: C
 
*** cblas_ssyr2k, cblas_dsyr2k: C
 
*** cblas_strmm, cblas_dtrmm: B
 
*** cblas_strsm, cblas_strsm: B
 
** vBLAS (idem)
 
*** SDOT: X, Y
 
*** SNRM2: X
 
*** SASUM: X
 
*** ISAMAX: X
 
*** SSWAP: X, Y
 
*** SCOPY: X, Y
 
*** SAXPY: X, Y
 
*** SROT: X, Y
 
*** SSCAL: X
 
*** SGEMV, A, X, Y
 
*** SGEMM: A, B, C
 
** vDSP (idem)
 
*** vDSP_sve_svesq, vDSP_sve_svesqD: __vDSP_A
 
*** vDSP_normalize, vDSP_normalizeD: __vDSP_A, __vDSP_C
 
 
 
== Windows 9x series ==
 
  
=== Windows 9x series unsupported ===
+
===== DB.TFieldType: new types added =====
* '''Old behaviour''': While 2.6.x formally didn't support the Windows 9x Series, 3rd party maintenance kept most FPC 2.6.x versions working with the Windows 9x series (Windows 95, 98/98SE, ME), and problems were the exception rather than the rule.
+
* '''Old behaviour:''' .
* '''New behaviour''': Starting from this compiler version, the Windows 9x series is not supported anymore.
+
* '''New behaviour:''' Some of new Delphi field types were added (ftOraTimeStamp, ftOraInterval, ftLongWord, ftShortint, ftByte, ftExtended) + corresponding classes TLongWordField, TShortIntField, TByteField; Later were added also ftSingle and TExtendedField, TSingleField
* '''Reason''': the Windows 9x series has been discontinued for a long time; there is no support (including support for newer Windows features) and no Microsoft online documentation. Supporting this platform has been increasingly difficult due to this and the number of users/developers interested in performing the development/test work.
+
* '''Reason for change:''' align with Delphi and open space for support of short integer and unsigned integer data types
* '''Remedy''': users that want to use FPC for Win9x development can continue to use earlier compiler versions (e.g. FPC 2.6.4).
+
* '''svn''': 47217, 47219, 47220, 47221; '''git''': c46b45bf
  
== Windows/x86_64 ==
+
==== DaemonApp ====
 +
===== TDaemonThread =====
 +
* '''Old behaviour:''' The virtual method ''TDaemonThread.HandleControlCode'' takes a single ''DWord'' parameter containing the control code.
 +
* '''New behaviour:''' The virtual method ''TDaemonThread.HandleControlCode'' takes three parameters of which the first is the control code, the other two are an additional event type and event data.
 +
* '''Reason for change:''' Allow for additional event data to be passed along which is required for comfortable handling of additional control codes provided on Windows.
 +
* '''svn''': 46327
  
=== Exception handling has been changed to be ABI-conformant  ===
+
===== TDaemon =====
 +
* '''Old behaviour:''' If an event handler is assigned to ''OnControlCode'' then it will be called if the daemon receives a control code.
 +
* '''New behaviour:''' If an event handler is assigned to ''OnControlCodeEvent'' and that sets the ''AHandled'' parameter to ''True'' then ''OnControlCode'' won't be called, otherwise it will be called if assigned.
 +
* '''Reason for change:''' This was necessary to implement the handling of additional arguments for control codes with as few backwards incompatible changes as possible.
 +
* '''svn''': 46327
  
* '''Old behaviour''': Exceptions were handled using platform-independent mechanism based on SetJmp/LongJmp.
+
==== FileInfo ====
* '''New behaviour''': Exceptions are handled using OS-provided means. The most important differences from generic handling are as follows:
+
* '''Old behaviour:''' The ''FileInfo'' unit is part of the ''fcl-base'' package.
** Every executable contains a <tt>.pdata</tt> section describing layout of function stack frames. This data is used to perform stack back-tracing. As a consequence, the backtraces generated when exception occurs are no longer dependent of code optimization settings. However, they may be different from ones produced by gdb.
+
* '''New behaviour:''' The ''FileInfo'' unit is part of the ''fcl-extra'' package.
** GNU binutils have troubles creating executables with <tt>.pdata</tt> sections. In particular, ld version < 2.22 crashes at such executables, and using GNU as together with internal linker will strip all <tt>.pdata</tt>, resulting in a non-working executable.
+
* '''Reason for change:''' Breaks up a cycle in build dependencies after introducing a RC file parser into ''fcl-res''. This should only affect users that compile trunk due to stale PPU files in the old location or that use a software distribution that splits the FPC packages (like Debian).
** An exception is handled in two phases. First phase determines the target frame (i.e. the 'except' statement that will handle the exception), the second phase does actual stack unwinding and executing code in 'finally' statements. In contrast, the generic mechanism is single-phase: it starts unwinding immediately and proceeds until an 'except' statement handles the exception or the stack runs out.
+
* '''svn''': 46392
* '''Reason''': Multiple compatibility issues with Windows and third-party DLLs (see http://bugs.freepascal.org/view.php?id=12974 and related issues)
 
* '''Remedy''': No changes are necessary unless your code relies on specific exception handling details. Build programs using FPC's internal assembler and linker, do not use GNU binutils. The entire feature can be disabled by cycling the compiler with <tt>OPT=-dDISABLE_WIN64_SEH</tt> in command line.
 
  
=== ''winwidestringalloc'' has been deprecated ===
+
==== Sha1 ====
 +
* '''Old behaviour:''' Sha1file silently did nothing on file not found.
 +
* '''New behaviour:''' sha1file now raises sysconst.sfilenotfound exception on fle not found.
 +
* '''Reason for change:''' Behaviour was not logical, other units in the same package already used sysutils.
 +
* '''svn''': 49166
  
* '''Old behaviour''': The ''winwidestringalloc'' variable enabled switching the WideString behaviour on Windows between COM BSTR (if set to true) and an internal UnicodeString-like container (if set to false).
+
==== Image ====
* '''New behaviour''': The ''winwidestringalloc"" has been deprecated and will be removed completely from the RTL code in the future.
+
===== FreeType: include bearings and invisible characters into text bounds =====
* '''Reason''': This setting predates the availability of the separate ''UnicodeString'' types, and was meant to enable Windows targets to use reference counted long strings. Nowadays, the ''UnicodeString'' type is available as an alternative on all platforms.
+
* '''Old behaviour:''' When the bounds rect was calculated for a text, invisible characters (spaces) and character bearings (spacing around character) were ignored. The result of Canvas.TextExtent() was too short and did not include all with Canvas.TextOut() painted pixels.
* '''Remedy''': Check whether you set <code>winwidestringalloc := false</code> in your program code and if so, replace all ''WideString'' declarations with ''UnicodeString''.
+
* '''New behaviour:''' the bounds rect includes invisible characters and bearings. Canvas.TextExtent() covers the Canvas.TextOut() area.
 +
* '''Reason for change:''' The text could not be correctly aligned to center or right, the underline and textrect fill could not be correctly painted.
 +
* '''svn''': 49629
  
== WinCE ==
+
==== Generics.Collections & Generics.Defaults ====
 +
* '''Old behaviour:''' Various methods had '''constref''' parameters.
 +
* '''New behaviour:''' '''constref''' parameters were changed to '''const''' parameters.
 +
* '''Reason for change:'''
 +
** Delphi compatibility
 +
** Better code generation especially for types that are smaller or equal to the ''Pointer'' size.
 +
* '''Remedy:''' Adjust parameters of method pointers or virtual methods.
 +
* '''git''': [https://gitlab.com/freepascal.org/fpc/source/-/commit/693491048bf2c6f9122a0d8b044ad0e55382354d 69349104]
  
=== Define ''UNICODE'' was changed to ''FPC_OS_UNICODE'' ===
+
== AArch64/ARM64 ==
 +
=== ''{''-style comments no longer supported in assembler blocks ===
 +
* '''Old behaviour''': The ''{'' character started a comment in assembler blocks, like in Pascal
 +
* '''New behaviour''': The ''{'' character now has a different meaning in the AArch64 assembler reader, so it can no longer be used to start comments.
 +
* '''Reason for change''': Support has been added for register sets in the AArch64 assembler reader (for the ld1/ld2/../st1/st2/... instructions), which also start with ''{''.
 +
* '''Remedy''': Use ''(*'' or ''//'' to start comments
 +
* '''svn''': 47116
  
* '''Old behaviour''': For arm-wince and i386-wince ''UNICODE'' was defined by default.
 
* '''New behaviour''': For arm-wince and i386-wince ''FPC_OS_UNICODE'' is defined by default.
 
* '''Reason''': For upcoming support for setting String to UnicodeString, the define ''UNICODE'' now is defined if the type String is currently defined as UnicodeString. This is also increases Delphi compatibility, as ''UNICODE'' is defined from Delphi 2009 on.
 
* '''Remedy''': Check for ''FPC_OS_UNICODE'' to decide whether the OS only provides a Unicode API (in the sense of Wide- or UnicodeString) and use ''UNICODE'' to decide whether the type String is currently defined as UnicodeString or not.
 
  
== Other ==  
+
== Darwin/iOS ==
  
=== Stabs support has been disabled for 64 bit targets ===
+
== Previous release notes ==
* '''Old behaviour''': While the default debug information format for 64 bit targets was DWARF (except for AIX, where it's Stabx), it was possible to switch it to Stabs via the -gs command line parameter.
+
{{Navbar Lazarus Release Notes}}
* '''New behaviour''': Only the DWARF debug format is still supported on 64 bit targets (except for AIX, where Stabx is used).
 
* '''Reason''': Stabs is not well-defined for 64 bit targets, nor well-supported by gdb on those same targets. This can lead to [http://bugs.freepascal.org/view.php?id=23365 problems]
 
* '''Remedy''': Do not use -gs when compiling for 64 bit targets. If you do so anyway, the compiler will display a warning and keep the previously set (supported) debug format.
 
  
== See also ==
 
* [[FPC New Features Trunk]]
 
 
[[Category:FPC User Changes by release]]
 
[[Category:FPC User Changes by release]]
 +
[[Category:Release Notes]]
 +
[[Category:Troubleshooting]]

Latest revision as of 18:32, 9 February 2024

About this page

Listed below are intentional changes made to the FPC compiler (trunk) since the previous 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

Precedence of the IS operator changed

  • Old behaviour: The IS operator had the same precedence as the multiplication, division etc. operators.
  • New behaviour: The IS operator has the same precedence as the comparison operators.
  • Reason: Bug, see [1].
  • Remedy: Add parenthesis where needed.

Visibilities of members of generic specializations

  • Old behaviour: When a generic is specialized then visibility checks are handled as if the generic was declared in the current unit.
  • New behaviour: When a generic is specialized then visibility checks are handled according to where the generic is declared.
  • Reason: Delphi-compatibility, but also a bug in how visibilities are supposed to work.
  • Remedy: Rework your code to adhere to the new restrictions.

Implementation Changes

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}
  • 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}
type
  tdynarray = array of byte;

procedure test(var arr); overload;
begin
  pbyte(arr)[0]:=1;
end;

procedure test(arr: tdynarray); overload;
begin
  test[0]:=1;
end;

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

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']
begin
end;

// becomes this
procedure Test; cdecl; public; alias:'foo';
begin
end;
  • 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 outside of that range
  • 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 would be expected, because $ffffffff was interpreted as "-1".
  • Remedy: Add Longint typecasts to values outside the valid range of a Longint.

Comp as a type rename of Int64 instead of an alias

  • Old behavior: On non-x86 as well as Win64 the Comp type is declared as an alias to Int64 (Comp = Int64).
  • New behavior: On non-x86 as well as Win64 the Comp type is declared as a type rename of Int64 (Comp = type Int64).
  • Reason:
    • This allows overloads of Comp and Int64 methods/functions
    • This allows to better detect properties of type Comp
    • Compatibility with Delphi for Win64 which applied the same reasoning
  • Remedy: If you relied on Comp being able to be passed to Int64 variables/parameters either include typecasts or add overloads for Comp.
  • svn: 43775

Routines that only differ in result type

  • Old behaviour: It was possible to declare routines (functions/procedures/methods) that only differ in their result type.
  • New behaviour: It is no longer possible to declare routines that only differ in their result type.
  • Reason: It makes no sense to allow this as there are situations where the compiler will not be able to determine which function to call (e.g. a simple call to a function Foo without using the result).
  • Remedy: Correctly declare overloads.
  • Notes:
    • As the JVM allows covariant interface implementations such overloads are still allowed inside classes for the JVM target.
    • Operator overloads (especially assignment operators) that only differ in result type are still allowed.
  • svn: 45973

Open Strings mode enabled by default in mode Delphi

  • Old behaviour: The Open Strings feature (directive $OpenStrings or $P) was not enabled in mode Delphi.
  • New behaviour: The Open Strings feature (directive $OpenStrings or $P) is enabled in mode Delphi.
  • Reason: Delphi compatibility.
  • Remedy: If you have assembly routines with a var parameter of type ShortString then you also need to handle the hidden High parameter that is added for the Open String or you need to disable Open Strings for that routine.
  • git: 188cac3b

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

System - buffering of output to text files

  • Old behaviour: Buffering was disabled only for output to text files associated with character devices (Linux, BSD targets, OS/2), or for output to Input, Output and StdErr regardless of their possible redirection (Win32/Win64, AIX, Haiku, BeOS, Solaris).
  • New behaviour: Buffering is disabled for output to text files associated with character devices, pipes and sockets (the latter only if the particular target supports accessing sockets as files - Unix targets).
  • Reason for change: The same behaviour should be ensured on all supported targets whenever possible. Output to pipes and sockets should be performed immediately, equally to output to character devices (typically console) - in case of console users may be waiting for the output, in case of pipes and sockets some other program is waiting for this output and buffering is not appropriate. Seeking is not attempted in SeekEof implementation for files associated with character devices, pipes and sockets, because these files are usually not seekable anyway (instead, reading is performed until the end of the input stream is reached).
  • Remedy: Buffering of a particular file may be controlled programmatically / changed from the default behaviour if necessary. In particular, perform TextRec(YourTextFile).FlushFunc:=nil immediately after opening the text file (i.e. after calling Rewrite or after starting the program in case of Input, Output and StdErr) and before performing any output to this text to enable buffering using the default buffer, or TextRec(YourTextFile).FlushFunc:=TextRec(YourTextFile).FileWriteFunc to disable buffering.
  • svn: 46863

System - type returned by BasicEventCreate on Windows

  • Old behaviour: BasicEventCreate returns a pointer to a record which contains the Windows Event handle as well as the last error code after a failed wait. This record was however only provided in the implementation section of the System unit.
  • New behaviour: BasicEventCreate returns solely the Windows Event handle.
  • Reason for change: This way the returned handle can be directly used in the Windows Wait*-functions which is especially apparent in TEventObject.Handle.
  • Remedy: If you need the last error code after a failed wait, use GetLastOSError instead.
  • svn: 49068

System - Ref. count of strings

  • Old behaviour: Reference counter of strings was a SizeInt
  • New behaviour: Reference counter of strings is now a Longint on 64 Bit platforms and SizeInt on all other platforms.
  • Reason for change: Better alignment of strings
  • Remedy: Call System.StringRefCount instead of trying to access the ref. count field by pointer operations or other tricks.
  • git: ee10850a57

System.UITypes - function TRectF.Union changed to procedure

  • Old behaviour: function TRectF.Union(const r: TRectF): TRectF;
  • New behaviour: procedure TRectF.Union(const r: TRectF);
  • Reason for change: Delphi compatibility and also compatibility with TRect.Union
  • Remedy: Call class function TRectF.Union instead.
  • git: 5109f0ba

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

Math Min/MaxSingle/Double

  • Old behaviour: MinSingle/MaxSingle/MinDouble/MaxDouble were set to a small/big value close to the smallest/biggest possible value.
  • New behaviour: The constants represent now the smallest/biggest positive normal numbers.
  • Reason for change: Consistency (this is also Delphi compatibility), see https://gitlab.com/freepascal.org/fpc/source/-/issues/36870.
  • Remedy: If the code really depends on the old values, rename them and use them as renamed.
  • svn: 44714

Random generator

  • Old behaviour: FPC uses a Mersenne twister generate random numbers
  • New behaviour: Now it uses Xoshiro128**
  • Reason for change: Xoshiro128** is faster, has a much smaller memory footprint and generates better random numbers.
  • Remedy: When using a certain randseed, another random sequence is generated, but as the PRNG is considered as an implementation detail, this does not hurt.
  • git: 91cf1774

Types.TPointF.operator *

  • Old behaviour: for a, b: TPointF, a * b is a synonym for a.DotProduct(b): it returns a single, scalar product of two input vectors.
  • New behaviour: a * b does a component-wise multiplication and returns TPointF.
  • Reason for change: Virtually all technologies that have a notion of vectors use * for component-wise multiplication. Delphi with its System.Types is among these technologies.
  • Remedy: Use newly-introduced a ** b, or a.DotProduct(b) if you need Delphi compatibility.
  • git: f1e391fb

CocoaAll

CoreImage Framework Linking
  • Old behaviour: Starting with FPC 3.2.0, the CocoaAll unit linked caused the CoreImage framework to be linked.
  • New behaviour: The CocoaAll unit no longer causes the CoreImage framework to be linked.
  • Reason for change: The CoreImage framework is not available on OS X 10.10 and earlier (it's part of QuartzCore there, and does not exist at all on some even older versions).
  • Remedy: If you use functionality that is only available as part of the separate CoreImage framework, explicitly link it in your program using the {$linkframework CoreImage} directive.
  • svn: 45767

DB

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
DB.TFieldType: new types added
  • Old behaviour: .
  • New behaviour: Some of new Delphi field types were added (ftOraTimeStamp, ftOraInterval, ftLongWord, ftShortint, ftByte, ftExtended) + corresponding classes TLongWordField, TShortIntField, TByteField; Later were added also ftSingle and TExtendedField, TSingleField
  • Reason for change: align with Delphi and open space for support of short integer and unsigned integer data types
  • svn: 47217, 47219, 47220, 47221; git: c46b45bf

DaemonApp

TDaemonThread
  • Old behaviour: The virtual method TDaemonThread.HandleControlCode takes a single DWord parameter containing the control code.
  • New behaviour: The virtual method TDaemonThread.HandleControlCode takes three parameters of which the first is the control code, the other two are an additional event type and event data.
  • Reason for change: Allow for additional event data to be passed along which is required for comfortable handling of additional control codes provided on Windows.
  • svn: 46327
TDaemon
  • Old behaviour: If an event handler is assigned to OnControlCode then it will be called if the daemon receives a control code.
  • New behaviour: If an event handler is assigned to OnControlCodeEvent and that sets the AHandled parameter to True then OnControlCode won't be called, otherwise it will be called if assigned.
  • Reason for change: This was necessary to implement the handling of additional arguments for control codes with as few backwards incompatible changes as possible.
  • svn: 46327

FileInfo

  • Old behaviour: The FileInfo unit is part of the fcl-base package.
  • New behaviour: The FileInfo unit is part of the fcl-extra package.
  • Reason for change: Breaks up a cycle in build dependencies after introducing a RC file parser into fcl-res. This should only affect users that compile trunk due to stale PPU files in the old location or that use a software distribution that splits the FPC packages (like Debian).
  • svn: 46392

Sha1

  • Old behaviour: Sha1file silently did nothing on file not found.
  • New behaviour: sha1file now raises sysconst.sfilenotfound exception on fle not found.
  • Reason for change: Behaviour was not logical, other units in the same package already used sysutils.
  • svn: 49166

Image

FreeType: include bearings and invisible characters into text bounds
  • Old behaviour: When the bounds rect was calculated for a text, invisible characters (spaces) and character bearings (spacing around character) were ignored. The result of Canvas.TextExtent() was too short and did not include all with Canvas.TextOut() painted pixels.
  • New behaviour: the bounds rect includes invisible characters and bearings. Canvas.TextExtent() covers the Canvas.TextOut() area.
  • Reason for change: The text could not be correctly aligned to center or right, the underline and textrect fill could not be correctly painted.
  • svn: 49629

Generics.Collections & Generics.Defaults

  • Old behaviour: Various methods had constref parameters.
  • New behaviour: constref parameters were changed to const parameters.
  • Reason for change:
    • Delphi compatibility
    • Better code generation especially for types that are smaller or equal to the Pointer size.
  • Remedy: Adjust parameters of method pointers or virtual methods.
  • git: 69349104

AArch64/ARM64

{-style comments no longer supported in assembler blocks

  • Old behaviour: The { character started a comment in assembler blocks, like in Pascal
  • New behaviour: The { character now has a different meaning in the AArch64 assembler reader, so it can no longer be used to start comments.
  • Reason for change: Support has been added for register sets in the AArch64 assembler reader (for the ld1/ld2/../st1/st2/... instructions), which also start with {.
  • Remedy: Use (* or // to start comments
  • svn: 47116


Darwin/iOS

Previous release notes