User Changes Trunk

From Free Pascal wiki
Revision as of 14:30, 11 December 2010 by Michalis (talk | contribs) (→‎Unit changes: FreeGlut -> UnloadGlut document)
Jump to navigationJump to search

About this page

Below you can find a list of intentional changes since the previous 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.

All systems

Usage Changes

Static keyword is enabled without switches and directives

  • Old behaviour: Using the static keyword required passing the -St switch to the compiler or using the {$STATIC on} directive.
  • New behaviour: The static keyword is now always enabled.
  • Effect: The -St switch has been deprecated and the {$STATIC on/off} directive no longer exists.
  • Reason: The compiler can now always correctly determine whether static is used as a modifier or as a field name, and recent Delphi versions support static class methods without any special switches.
  • Remedy: Adjust your build scripts and source code by removing all -St parameters and and {$STATIC on/off} statements.

Language changes

Passing derived classes to var- and out-parameters

  • 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.
  • 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}

type

 ta = class
 end;
 tb = class(ta)
 end;

var

 b: tb;

procedure test(var a: ta); begin

 a:=ta.create;
 // now b contains an instance of type "ta"

end;

begin

 b:=nil;
 test(b);

end. </delphi> The compiler used to accept the above program, but now it will give an error at the call to test.

  • Reason: As the example above demonstrates, allowing this behaviour circumvents the language's type checking. This change is also Delphi-compatible.
  • 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.

Array of const parameters and cdecl routines

  • Old behaviour: It was possible to have non-external cdecl routines with an array of const parameter.
  • New behaviour: Cdecl routines with an array of const parameter now always must be external.
  • 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.
  • 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.

String constants longer than 255 chars

  • Old behaviour: String constants longer than 255 chars were silently cut off after 255 chars under certain circumstances.
  • New behaviour: String constants longer than 255 chars cause an error in $H- state, in $H+ state an ansistring constant is generated.
  • Reason: Cutting of strings silently sounds like bad behaviour of the compiler.
  • Remedy: Manually truncate string constants longer than 255 chars or use $H+

Short/Ansistring typed constants containing widechars/unicodechars

  • Old behaviour: The compiler accepted shortstring and ansistring typed constant declarations to which widestring or unicodestring constants were assigned (string constants containing widechars/unicodechars, i.e., character constants of the form #$xxx, #$xxxx or #yyy with yyy > 255, or character literals outside the ASCII range while the code page is different from the default one).
  • New behaviour: The compiler will reject such declarations now.
  • Example:

<delphi> {$codepage utf8}

{ this example assumes that the source file has been saved using utf-8 encoding }

const

 s1: shortstring = 'éà';
 s2: ansistring = #$094#$06D;
 s3: ansistring = #267#543;

begin end. </delphi> All three declarations above used to be accepted, but are now rejected. The reasons are that

  • the string assigned to s1 has been encoded as an utf-8 string and contains non-ASCII characters
  • the string assigned to s2 contains hexadecimal character constants declared with more than 2 digits
  • the string assigned to s3 contains character values > 255

In all cases, the practical upshot is that the string on the right hand side of the assignment will be treated as a wide/unicodestring constant at compile time.

  • Reason: The encoding of shortstrings and ansistrings is always the system (ansi) encoding at run time. This system encoding can be different every time the program is run, and hence cannot be determined at compile time. It is therefore not possible for the compiler to convert a wide/unicodestring constant to an ansi/shortstring at compile time. See also bug report 16219.
  • Remedy: If you require the string's characters to contain particular ordinal values, declare the string constant as a sequence of byte-sized values (i.e., values <= 255, and in case of hexadecimal notation only use two digits), or do not use any {$codepage xxx} directive nor an UTF BOM. In all other cases, declare the typed constant as a widestring or unicodestring.

Implicit "result" variable in MacPas mode

  • Old behaviour: In MacPas mode, all functions could automatically access the function result via the implicitly defined result alias (like in Delphi and ObjFPC mode).
  • New behaviour: The result alias is no longer defined by default in MacPas mode.
  • Reason: It is not available in Mac Pascal compilers either, and can mask other identifiers thereby changing the behaviour of code.
  • Remedy: You can reenable the result alias by adding {$modeswitch result} to your program code (after any {$mode macpas} statements), or by using the -Mresult command line option (after any -Mmacpas parameter, and provided there are not {$mode xxx} directives in the source).

Implementation changes

Order of parameters in RTTI

  • 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 on i386 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.
  • New behaviour: The parameters are always stored from left to right in the RTTI, i.e., as they appear in the source code.
  • Effect: Code parsing RTTI information for the purpose of figuring out in which order to pass the parameters will no longer work.
  • Reason: Delphi compatibility, making the information more useful for IDEs.
  • 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.

Sizes of sets in TP/Delphi mode

  • Old behaviour: {$packset fixed} was the default for all language modes. This packs a set of up to 32 elements in 4 bytes, and all other sets in 32 bytes.
  • New behaviour: The default in TP/Delphi mode is now {$packset 1}
  • 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. Sets with 17..32 elements will remain 4 bytes, but after that every additional 8 elements the size will increase by 1 byte up to 249..256 elements, which will result in a set of 32 bytes.
  • Reason: TP/Delphi compatibility.
  • Remedy: If you have code written in TP/Delphi mode that depends on the old packset setting, add {$packset fixed} to the source (after setting the syntax mode to Delphi/TP, since the mode switching changes the packset setting). This is backward compatible with at least FPC 2.2.4 and later.

Constants in mixed signed/unsigned 64 bit expressions

  • Old behaviour: Some comparisons involving a negative 64 bit constant and a unsigned 64 bit variable were handled incorrectly by the compiler: the negative constant was internally explicitly typecasted to the unsigned type.
  • New behaviour: The compiler will now correctly use the original value of the negative constant.
  • Effect: Some comparisons that previously evaluated to "true" at run time, may now evaluate to "false" at compile time.
  • Example:

<delphi> const

 // note that 64 bit hexadecimal constants are always parsed as int64
 // (also by previous FPC releases)
BIG_A = $AB09CD87EF653412;

var

q : qword;

begin

q := qword(BIG_A);
if (q = BIG_A) then
  writeln('same')
else
  writeln('different');

end. </delphi> The above program used to print 'same', but will now print 'different'

  • Reason: The compiler must not automatically convert negative constants to positive equivalents like that.
  • Remedy: Explicitly typecast any constants that are supposed to be unsigned 64 bit constants to qword. E.g., in the above example, use BIG_A = qword($AB09CD87EF653412).

Parameter passing and returning results on x86-64 platforms (except for Win64)

  • Old behaviour: The compiler did not correctly implement the official x86-64 ABI for passing parameters and returning function results in all cases. In particular, records were always either passed/returned via integer registers or memory.
  • New behaviour: The compiler now correctly adheres to the official x86-64 ABI under all circumstances on platforms that require this. In particular, certain records are now passed/returned via SSE registers.
  • Effect: Pure assembler routines based on the old conventions may no longer work on non-Win64 platforms. Win64 follows Microsoft's own variant of the x86-64 ABI and this one was already implemented correctly in the compiler, and hence has not been changed.
  • Reason: Interoperability with code generated by other compilers.
  • Remedy: Adjust your assembler code so it expects parameters to be passed conform to the official x86-64 ABI

Overflow/Rangechecking for floating point constants

  • Old behavior: When a NaN floating point constant was assigned to a variable in {$R+} or {$Q+} mode, the compiler reported an error.
  • New behaviour: {$R+} and {$Q+} no longer cause errors when assigning a NaN constant to a variable. The new $ieeeerrors setting can now be used to control whether or not such assignments should cause an error.
  • Reason: Consistency, Delphi compatibility (it does not support the {$ieeeerrors+/-} setting, but it does not give an error based on the {$r/q} settings either) .
  • Remedy: Add {$ieeeerrors+} to your code or add -C3 on the command line.

Unit changes

xmlrpc unit and utils have been removed

  • Old behaviour: There was an xmlrpc unit and a related demo program called mkxmlrpc.
  • New behaviour: These sources have been removed in svn trunk, and deprecated in the svn fixes branch.
  • Reason: The code was unmaintained and had been broken for years, and has been replaced by new functionality in fcl-web and fcl-json.
  • Remedy: Use fcl-web or, if adapting the source code is not feasible, obtain the xmlrpc-related sources from older FPC versions.

OpenSSL

  • Old behaviour: The openssl unit contained an EVP_PKEY type.
  • New behaviour: The EVP_PKEY type has been renamed into PEVP_PKEY.
  • Reason: Consistency with other similar types and with the original C declaration.
  • Remedy: Make the same typename change in your source code.

Graph unit aspect ratio changes in Arc and PieSlice

  • Old behaviour: Graph unit procedures Arc and PieSlice always assumed a 1:1 aspect ratio, regardless of current mode's aspect ratio.
  • New behaviour: Arc and PieSlice now respect the current aspect ratio.
  • Reason: Borland Pascal compatibility; better (i.e. more 'circular') looks of arcs and pie slices in modes with weird aspect ratios like 640x200; consistency with the Circle procedure, which already respects the current aspect ratio.
  • Remedy: This change is only likely to affect you, if you use a graphical mode with an aspect ratio, different than 1:1. Note that VGA 640x480 and higher modes usually always have a 1:1 aspect ratio. 320x200, 640x200, 640x350 and 640x400, however, do not. If you use one of these modes and, for some reason, don't want aspect ratio compensation in Arc and PieSlice, either call:
SetAspectRatio(10000, 10000)

immediately after InitGraph (this will also change the behaviour of Circle) or replace:

Arc(X, Y, StAngle, EndAngle, Radius) with Ellipse(X, Y, StAngle, EndAngle, Radius, Radius)

and

PieSlice(X, Y, StAngle, EndAngle, Radius) with Sector(X, Y, StAngle, EndAngle, Radius, Radius)

Graph unit aspect ratio changes in GraphDefaults

  • Old behaviour: The GraphDefaults procedure used to reset the current aspect ratio to 1:1, regardless of the current mode's default aspect ratio.
  • New behaviour: GraphDefaults no longer changes the current aspect ratio.
  • Reason: Borland Pascal compatibility; bug fix for applications that call GraphDefaults in modes with an aspect ratio different than 1:1 and still want to use aspect ratio compensation, since the old behaviour effectively disabled any aspect ratio compensation.
  • Remedy: If you want to reset the current aspect ratio to 1:1, just call:
SetAspectRatio(10000, 10000)

TThread.Suspend and TThread.Resume are deprecated

  • Old behaviour: Suspend would suspend the thread, if the platform allowed it, Resume would resume an explicitely suspended thread, or a thread created suspended.
  • New behaviour: Suspending running threads is deprecated. Creating threads suspended is still supported, and a new method START is added for this.
  • Reason: Both Embarcadero Delphi (D2010+) compatibility, and the unreliability and implementation trouble to implement running thread suspension on other platforms. Probably similar concerns played a part in Embarcaderoes decision.
  • Remedy: For threads created suspended, replace resume with start. For suspending running threads: rewrite so this functionality is no longer needed.

Note that there are no short term plans to remove resume() to start suspended threads. If you want to share code with old Delphi versions, using resume will remain working for starting threads that were created suspended for several FPC releases to come. Just ignore the warning.

IInterface.QueryInterface, ._AddRef and ._Release definitions have been changed

  • Old behaviour: The IInterface.QueryInterface, ._AddRef and ._Release methods were defined stdcall and the IID was passed as const.
  • New behaviour: These methods are defined stdcall on Windows and cdecl on the other operating systems. The IID parameter has become a constref.
  • Reason: These methods are used for communicating with COM on Windows. These changes make it possible to interface with XPCom from Mozilla, which is cross-platform and similar to COM/Corba.
  • Remedy: If one of these methods is overridden, they have to be defined as follows:
function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND}; override;
function _AddRef: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND}; override;
function _Release: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND}; override;

Default TFPPixelCanvas brush style

  • Old behaviour: A brush in TFPPixelCanvas would start with the style bsClear
  • New behaviour: Now it starts with the style bsSolid
  • Reason: Starting with bsSolid is more intuitive and is also the state in which LCL brushes start.
  • Remedy: Initialize the brush to bsClear after creating your TFPPixelCanvas if your code depended on it starting in this state.

thread_count removed from system unit (win32,win64,wince, symbian, nativent)

  • Old behaviour: There was a variable called thread_count in the system unit of the targets win32,win64,wince, symbian, nativent
  • New behaviour: The variable has been removed.
  • Reason: The behaviour of the variable was wrong and cannot be fixed, see also http://bugs.freepascal.org/view.php?id=18089
  • Remedy: Since the value of the variable was unpredictable, there was probably no use of it.

Locale global variables are deprecated

  • Old behaviour: For every locale configuration a variable alias existed (currencystring, *dateformat) using an "absolute" modifier.
  • New behaviour: These variable now have the "deprecated" modifier, and a warning is emitted if you use one.
  • Reason: FPC has supported the use of these variables in a record since before 2000 called DefaultFormatSettings, Delphi XE now follows suit with "Formatsettings". In time this might remove the need for "absolute" usage.
  • Remedy: Use (Default)Formatsettings as much as possible. Note that that it will still be quite some time before these are actually removed.

Glut.FreeGlut function renamed to UnloadGlut

  • Old behaviour: Glut unit contained a function called FreeGlut.
  • New behaviour: This function is now renamed to UnloadGlut.
  • Reason: We now include a FreeGlut unit, exposing http://freeglut.sourceforge.net/ -specific functionality. Function name "FreeGlut" inside Glut unit would cause name clashes and confusion (as it's not related to freeglut library).
  • Remedy: Make the same rename in your source code.

x86 platforms

Operation size of pushf/popf/pusha/popa in Intel-style inline assembly

  • Old behaviour: The default operation size of the pushf/popf/pusha/popa in Intel-style inline assembly was the native size (32 bit on i386, 64 bit on x86-64).
  • New behaviour: The default operation size of these opcodes is now always 16 bit in Intel-style inline assembly. In AT&T-style inline assembly, the size remains the native size.
  • Reason: This is how the behaviour of these opcodes is defined in the Intel manuals, and it is also Delphi-compatible. The behaviour was not changed in AT&T-inline assembly because that dialect defines the default size of these operations as the native size.
  • Remedy: Explicitly specify the size when using such operations, e.g. pushfd, popfq, pushad, ... Note that pusha*/popa* do not exist on x86-64, and neither do pushfd/popfd (the compiler previously however erroneously accepted these opcodes when compiling for x86-64).