Difference between revisions of "User Changes Trunk"

From Lazarus wiki
Jump to navigationJump to search
(→‎Implementation changes: - default packset change)
m (Fix typos)
 
(422 intermediate revisions by 30 users not shown)
Line 1: Line 1:
 
== About this page==
 
== About this page==
  
Below you can find a list of intentional changes since the [[User_Changes_2.4.0|upcoming release branched off]] not yet scheduled for inclusion in a next fixes release that can change the behaviour of previously working code, along with why these changes were performed and how you can adapt your code if you are affected by them.
+
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]].
 +
 
 +
Please add revision numbers to the entries from now on. This facilitates moving merged items to the user changes of a release.
  
 
== All systems ==
 
== All systems ==
  
===Usage Changes===
+
=== 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 [https://bugs.freepascal.org/view.php?id=35909].
 +
* '''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.
  
=== Language changes ===
+
=== Implementation Changes ===
  
==== Passing derived classes to var- and out-parameters====
+
==== 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 [https://bugs.freepascal.org/view.php?id=35580 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)
  
* '''Old behaviour''': If a routine was declared with a var- or out-parameter of a certain class type, the compiler also allowed passing derived classes to this parameter.
+
<syntaxhighlight lang="pascal">
* '''New behaviour''': The compile-time type of a class passed to a routine now has to match the declared parameter type exactly in case of var- and out-parameters.
 
* '''Example''':
 
<delphi>
 
 
{$mode objfpc}
 
{$mode objfpc}
 +
type
 +
  tdynarray = array of byte;
  
type
+
procedure test(var arr); overload;
   ta = class
+
begin
  end;
+
   pbyte(arr)[0]:=1;
 +
end;
  
  tb = class(ta)
+
procedure test(arr: tdynarray); overload;
   end;
+
begin
 +
   test[0]:=1;
 +
end;
  
 
var
 
var
   b: tb;
+
   regulararray: array[1..1] of byte;
 +
begin
 +
  regulararray[1]:=0;
 +
  test(arr);
 +
  writeln(arr[0]); // writes 0, because it calls test(tdynarr)
 +
end.
 +
</syntaxhighlight>
 +
* '''svn''': 42118
  
procedure test(var a: ta);
+
==== 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:
 +
<syntaxhighlight lang="pascal">
 +
// this
 +
procedure Test; cdecl; [public,alias:'foo']
 
begin
 
begin
  a:=ta.create;
 
  // now b contains an instance of type "ta"
 
 
end;
 
end;
  
 +
// becomes this
 +
procedure Test; cdecl; public; alias:'foo';
 
begin
 
begin
  b:=nil;
+
end;
  test(b);
+
</syntaxhighlight>
end.
+
* '''svn''': 42402
</delphi>
+
 
The compiler used to accept the above program, but now it will give an error at the call to ''test''.
+
==== Type information contains reference to attribute table ====
* '''Reason''': As the example above demonstrates, allowing this behaviour circumvents the language's type checking. This change is also Delphi-compatible.
+
* '''Old behavior''': The first field of the data represented by ''TTypeData'' is whatever the sub branch of the case statement for the type contains.
* '''Remedy''': Rewrite the affected code so it that all var/out-parameters and the class types passed to them match exactly. There are ways to circumvent the type checking at the caller side by using explicit type conversions, but using such hacks is strongly discouraged since the resulting code is not type-safe.
+
* '''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:''' [https://gitlab.com/freepascal.org/fpc/source/-/commit/188cac3bc6dc666167aacf47fedff1a81d378137 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:''' [https://gitlab.com/freepascal.org/fpc/source/-/commit/ee10850a5793b69b19dc82b9c28342bdd0018f2e 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:''' [https://gitlab.com/freepascal.org/fpc/source/-/commit/5109f0ba444c85d2577023ce5fbdc2ddffc267c8 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
  
====''Array of const'' parameters and cdecl routines====
+
==== 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
  
* '''Old behaviour''': It was possible to have non-external ''cdecl'' routines with an ''array of const'' parameter.
+
==== Types.TPointF.operator * ====
* '''New behaviour''': ''Cdecl'' routines with an ''array of const'' parameter now always must be external.
+
* '''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.
* '''Reason''': In FPC, adding an ''array of const'' parameter to a ''cdecl'' routine has the same effect as adding the ''varargs'' modifier. It means that the routine takes a C-style variable number of arguments. There is however no way in (Free) Pascal to access these arguments on the callee side. This change means that both ''varargs'' and ''array of const'' are treated consistently, since ''varargs'' routines already had to be external.
+
* '''New behaviour:''' <code>a * b</code> does a component-wise multiplication and returns <code>TPointF</code>.
* '''Remedy''': Remove the ''cdecl'' specifier and use a Pascal-style ''array of const'', or implement the routine in C and add ''external'' to the Pascal declaration.
+
* '''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.
 +
* '''Remedy:''' Use newly-introduced <code>a ** b</code>, or <code>a.DotProduct(b)</code> if you need Delphi compatibility.
 +
* '''git:''' [https://gitlab.com/freepascal.org/fpc/source/-/commit/f1e391fb415239d926c4f23babe812e67824ef95 f1e391fb]
  
==== Abstract and Sealed class modifiers ====
+
==== CocoaAll ====
* '''Old behaviour''': It was possible to have ''abstract'' or ''sealed'' fields immediately following the ''class'' keyword.
+
===== CoreImage Framework Linking =====
* '''New behaviour''': The compiler now interprets ''abstract'' and ''sealed'' as class modifiers if they immediately follow the ''class'' keyword.
+
* '''Old behaviour''': Starting with FPC 3.2.0, the ''CocoaAll'' unit linked caused the ''CoreImage'' framework to be linked.
* '''Example''':
+
* '''New behaviour''': The ''CocoaAll'' unit no longer causes the ''CoreImage'' framework to be linked.
<delphi>
+
* '''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).
{$mode objfpc}
+
* '''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.
type
+
* '''svn''': 45767
  TSomeClass1 = class
 
    abstract: integer;
 
  end;
 
  
  TSomeClass2 = class
+
==== DB ====
    sealed: integer;
+
===== TMSSQLConnection uses TDS protocol version 7.3 (MS SQL Server 2008) =====
  end;
+
* '''Old behaviour:''' TMSSQLConnection used TDS protocol version 7.0 (MS SQL Server 2000).
</delphi>
+
* '''New behaviour:''' TMSSQLConnection uses TDS protocol version 7.3 (MS SQL Server 2008).
The above code will no longer compile.
+
* '''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.
* '''Reason''': ''abstract'' and ''sealed'' are now the class modifiers, which is Delphi-compatible
+
* '''svn''': 42737
* '''Remedy''': Separate the ''abstract'' or ''sealed'' field name from the ''class'' keyword with a visibility section (''published'', ''public'', ...) or with another field declaration.
 
  
=== Implementation changes ===
+
===== 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
  
====Order of parameters in RTTI====
+
==== DaemonApp ====
* '''Old behaviour''': The order in which the parameter information for a function was stored in the RTTI depended on the function's calling convention. If the calling convention <u>on i386</u> passed parameters from left-to-right, parameters were stored from left to right (regardless of the actual platform, which was a bug in itself), otherwise they were stored from right to left.
+
===== TDaemonThread =====
* '''New behaviour''': The parameters are always stored from left to right in the RTTI, i.e., as they appear in the source code.
+
* '''Old behaviour:''' The virtual method ''TDaemonThread.HandleControlCode'' takes a single ''DWord'' parameter containing the control code.
* '''Effect''': Code parsing RTTI information for the purpose of figuring out in which order to pass the parameters will no longer work.
+
* '''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''': Delphi compatibility, making the information more useful for IDEs.
+
* '''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.
* '''Remedy''': Adjust your code so it always expects parameters to appear in the RTTI ordered from left to right. In the future, we will also add the calling convention itself to the RTTI (like Delphi), so you can use that information to reorder the parameters in case you want to use this information to call the routine.
+
* '''svn''': 46327
  
====Sizes of sets in TP/Delphi mode====
+
===== TDaemon =====
* '''Old behaviour''': {$packset 4} was the default for all language modes
+
* '''Old behaviour:''' If an event handler is assigned to ''OnControlCode'' then it will be called if the daemon receives a control code.
* '''New behaviour''': The default in TP/Delphi mode is now {$packset 1}
+
* '''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.
* '''Effect''': In those language modes the size of sets with 1..8 elements will now be 1 byte, and the size of sets with 9..16 elements will be two bytes.
+
* '''Reason for change:''' This was necessary to implement the handling of additional arguments for control codes with as few backwards incompatible changes as possible.
* '''Reason''': TP/Delphi compatibility.
+
* '''svn''': 46327
* '''Remedy''': If you have code written in TP/Delphi mode that depends on the old packset setting, add {$packset 4} to the source. This is backward compatible.
 
  
=== Types changes ===
+
==== 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
  
====TObject class declaration====
+
==== Sha1 ====
* '''Old behaviour''': TObject class did not have UnitName, Equals, GetHashCode, ToString methods.
+
* '''Old behaviour:''' Sha1file silently did nothing on file not found.
* '''New behaviour''': Those methods were added to the TObject class.
+
* '''New behaviour:''' sha1file now raises sysconst.sfilenotfound exception on fle not found.
* '''Effect''': Compiler produces warnings in delphi mode and errors in objfpc mode if user classes have the same identifier(s).
+
* '''Reason for change:''' Behaviour was not logical, other units in the same package already used sysutils.
* '''Reason''': Delphi compatibility, these methods are present in the TObject class since Delphi 2009.
+
* '''svn''': 49166
* '''Remedy''': Adjust your code so it does not conflict with the TObject class members. Override TObject method where is possible or rename/reintroduce identifier in other case.
 
  
=== Unit changes ===
+
==== 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''': [https://gitlab.com/freepascal.org/fpc/source/-/commit/693491048bf2c6f9122a0d8b044ad0e55382354d 69349104]
  
====Daemonapp unit moved to new fcl-extras package ====
+
== AArch64/ARM64 ==
* '''Old behaviour''': unit Daemonapp resided in package fcl-base.
+
=== ''{''-style comments no longer supported in assembler blocks ===
* '''New behaviour''': unit Daemonapp resides in package fcl-extra.
+
* '''Old behaviour''': The ''{'' character started a comment in assembler blocks, like in Pascal
* '''Effect''': On OSes that have a package for every directory in packages, daemonapp seems to be missing if fcl-extra is not installed.
+
* '''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''': Breaking dependency cycles in the FCL, most notably on Windows.
+
* '''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''': On operating systems where a package in packages/ corresponds to a separate package to install (like on Debian), an additional package corresponding to fcl-extra must be installed
+
* '''Remedy''': Use ''(*'' or ''//'' to start comments
 +
* '''svn''': 47116
  
====DOM unit: no longer uses avl_tree for node search optimization====
 
Note: This is an implementation-only change. Nevertheless, it's worth documenting and explanation.
 
* '''Old behaviour''': each 'parent' DOM node (Elements and Attributes, in the first place) had an associated TAvgLvlTree object, that was used as child node node index, and intended to speed up the <code>TDOMNode.FindNode</code> method by replacing linear search by binary search.
 
* '''New behaviour''': the TAvgLvlTree is no longer used, and <code>TDOMNode.FindNode</code> method uses a linear search.
 
* '''Effect''': The XML parsing speed has increased about twice, and average memory usage of a DOM document has decreased by about 75%. The performance of the <code>TDOMNode.FindNode</code> method, and methods of TXMLConfig class (xmlcfg unit), may become lower in some scenarios.
 
* '''Reason''': The optimization offered by child node indexing was applicable only to one particular usage case: XML config files, which require all node names within a single parent to be unique. The memory/performance penalty caused for all other usage cases has become way too big.
 
* '''Remedy''': If you experience slowdown of your code using TXMLConfig class from xmlcfg unit, consider replacing xmlcfg with a newer xmlconf unit. Then, use <code>OpenKey</code> and <code>CloseKey</code> methods to limit the amount of searching in the DOM.
 
* '''Example''':
 
<delphi>
 
// the code like this
 
uses xmlcfg;
 
...
 
begin
 
  config.WriteString('the/very/long/path/value1', string1);
 
  config.WriteString('the/very/long/path/value2', string2);
 
  config.WriteString('the/very/long/path/value3', string3);
 
  ...
 
end;
 
  
// can be changed to:
+
== Darwin/iOS ==
uses xmlconf;
 
...
 
begin
 
  config.OpenKey('the/very/long/path');
 
  config.WriteString('value1', string1);
 
  config.WriteString('value2', string2);
 
  config.WriteString('value3', string3);
 
  config.CloseKey;
 
end;
 
// in this example, 'the/very/long/path' will be searched only once rather than 3 times,
 
// which will improve the performance.
 
</delphi>
 
  
====MacOSAll unit: changed parameter types====
+
== Previous release notes ==
 +
{{Navbar Lazarus Release Notes}}
  
* '''Old behavior''': The old headers were a combination of the original Apple-written Pascal headers and translated C headers. The Pascal headers were written for compilers that did not support unsigned 32 bit types, and in many cases used "var" parameters where the actual parameter was an array in C.
+
[[Category:FPC User Changes by release]]
* '''New behaviour''': The new headers have all been translated from the latest Mac OS X 10.6 headers for 64 bit and iPhoneOS support. As a result, several parameters types have changed.
+
[[Category:Release Notes]]
* '''Remedy''': Either adjust your code, or file bug reports asking to revert to the old signatures (especially for deprecated routines that won't be updated in the future anymore anyway, this should be no problem).
+
[[Category:Troubleshooting]]
* '''Changes:'''
 
** Many cases where signed parameters were turned into unsigned parameters and vice versa, too many to list (due to differences between the classic Pascal headers and the new C headers)
 
** ATSFontFindFromContainer: ioArray var -> ptr because array
 
** ATSFontGetFileSpecification: oFile FSSpec -> ATSFSSpec (was translation error?)
 
** CFNetworkCopyProxiesForAutoConfigurationScript: got extra CFErrorRef para
 
** CMGetDeviceFactoryProfiles: defaultProfID var -> ptr, because can be nil
 
** CMIterateColorDevices: seed and count var -> ptr, because can be nil
 
** CMIterateDeviceProfiles: seed and count var -> ptr, because can be nil
 
** CMSetDeviceProfiles: profileScope and deviceProfiles const -> ptr, because  can be nil
 
** ConvertFromUnicodeToScriptCodeRun: oScriptCodeRuns var -> ptr because array
 
** ConvertFromUnicodeToTextRun: oEncodingRuns var -> ptr because array
 
** CreateUnicodeToTextRunInfo: iUnicodeMappings var -> ptr because array
 
** DCMCreateFieldInfoRecord: findMethods var -> ptr because array
 
** DCMGetFieldFindMethods: findMethods var -> ptr because array
 
** GetIconRefFromFileInfo: outlabel var -> ptr because can be nil
 
** HIImageViewCreate: last parameter ControlRef -> HIViewRef
 
** HIViewNewTrackingArea: outRef var -> ptr because can be nil in 10.5+
 
** LAGetEnvironmentList: environmentList var -> ptr because array
 
** LAListAvailableDictionaries: dictionaryList and opened var -> ptr because array
 
** LSGetApplicationForURL: outAppRef and outAppURL var -> ptr because can be nil
 
** LocaleOperationGetLocales: localeVariantList var -> ptr because can be nil
 
** MPWaitOnQueue: param1-3 value -> var because "void **" in C
 
** QTVRSetBackBufferImagingProc: areasOfInterest var -> ptr because array
 
** QueryUnicodeMappings: oReturnedMappings var -> ptr because array
 
** TECConvertTextToMultipleEncodings: outEncodingsBuffer var -> ptr because array
 
** TECFlushMultipleEncodings: outEncodingsBuffer var -> ptr because array
 
** TECSniffTextEncoding: numErrsArray and numFeaturesArray var -> ptr because array
 
** FSCreateResFile: catalogInfo const -> ptr because can be nil
 

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