Sign in Join
Wiki copytemporary

Revision 2 of 2, by Trev on 3-1-2020. The page as it is now.

User Changes 3.0

About this page

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

All systems

Implementation changes

Exception type for object reference checking changed

Literal storage memory has been made read-only

pascal
uses sysutils;
 var
   s: ansistring;
 begin
   s := 'ansi string';
   Writeln(AnsiStrUpper(pchar(s)));
   s := 'ansi string';
   Writeln(s);
 end.

would modify the contents of data segment and print

text
ANSI STRING
ANSI STRING

UNICODE define depends on default string type instead of on target platform

RTTI changes

RTTI for Pointers and Class References

RTTI for AnsiStrings

RTTI for Arrays

RTTI for Records

RTTI for Procedural Variables

Usage example
pascal
program RTTIInfo;

{$mode objfpc}{$H+}
uses
  typinfo;

type
  CP866String = type AnsiString(866);
  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);
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
  if Info^.Kind <> tkProcedure then
    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;

procedure DescribeAnsiString(Info: PTypeInfo);
var
  Data: PTypeData;
begin
  if Info^.Kind <> tkAString then
    Exit;
  Data := GetTypeData(Info);
  if Data^.CodePage = 0 then
    WriteLn('AnsiString')
  else
    WriteLn('type AnsiString(',Data^.CodePage,');');
end;

procedure DescribeArray(Info: PTypeInfo);
var
  Data: PTypeData;
  Res: String;
  I: Integer;
begin
  if Info^.Kind <> tkArray then
    Exit;
  Data := GetTypeData(Info);
  Res := 'array[';
  for I := 0 to Data^.ArrayData.DimCount - 1 do
  begin
    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);
var
  Data: PTypeData;
begin
  if Info^.Kind <> tkPointer then
    Exit;
  Data := GetTypeData(Info);
  if Data^.RefType = nil then
    WriteLn('Pointer;')
  else
    WriteLn('^', Data^.RefType^.Name, ';');
end;

begin
  DescribeProcedure(TypeInfo(TProc));
  DescribeAnsiString(TypeInfo(CP866String));
  DescribeArray(TypeInfo(TArr));
  DescribePointer(TypeInfo(PArr));
  DescribePointer(TypeInfo(Pointer));
end.

Unit changes

DB

TBookmark TBookmarkstr and TDataset.Bookmark change to Delphi2009+ compatible definitions
TBufDataset.SaveToFile, SaveToStream: Binary Format (dfBinary) of saved data changes
pascal
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;

initialization
  RegisterDatapacketReader(TOldFpcBinaryDatapacketReader, dfBinary);
end.
TDataPacketReader class structure changes
TSQLScript supports :, backtick quotes and explicit COMMIT/COMMIT RETAIN
TMySQLxxConnection (mysqlconn.inc) VARCHAR columns are always mapped to TStringFields
TSQLite3Connection INTEGER PRIMARY KEY columns are mapped to TAutoIncFields
TSQLite3Connection: Boolean True values are stored as 1 not as -1

FileNameCaseSensitive and FileNameCasePreserving in unit System

Some longtime deprecated functions in unit Unix have been removed.

statfs has been renamed to fpstatfs

RTLeventsync has been removed

TVersionInfo (fileinfo unit) re-implemented in a platform independent way

shlobj symbols removed from unit Windows

process OnForkEvent implementation

Extention -> Extension typo fix

SysUtils: File names starting with a period are not considered to be extensions

System: Error messages are now written to stderr

TZipper: writes zip files with zip standard / instead of \ directory separators

Language Changes

AnsiStrings are now codepage-aware

Variant overload preference for string types

Variant conversion preference for widechar

Default values in implementation but not in interface/forward declaration

Default values are now properly typechecked

"strict protected" visibility modifier

Support for type helpers added

pascal
{$mode objfpc}
type
  helper = LongInt;

  otherhelper = type helper;

The above code will no longer compile.

pascal
{$mode objfpc}
type
  helper = LongInt;

  otherhelper = type &helper;

"strict protected" and "protected" visibility modifier in extended records

"static" directive on non-class methods

"static" directive on class operators

Classes implementing forward-declared interfaces

Using the function name as alias for loading its current result value in MacPas mode

nostackframe forbidden for Pascal subroutines

Conversion preference of pansichar to various string types

Comparative operators can have any result type

pascal
SQLResult := Database.Query(
  Select(
    [ PersonsTable.FirstName, PersonsTable.LastName ],
    [ PersonsTable ],
    [ 
      PersonsTable.Country = 'NL',
      PersonsTable.Age >= 25
    ]
  )
);

True and False are not keywords anymore

pascal
const
  False = 0;
  True = 1;

For-in loop variable cannot be assigned to anymore

Casting integer variables to floating point

pascal
var
  i: int64;
begin
  i:=1389038897;
  writeln(Double(i))
  writeln(Double(1389038897))
end.

Unix platforms

cthreads: critical sections and recursive mutex support

Darwin platforms

Location of certain function result types on Darwin/i386 and iPhoneSim/i386

Default assembler for Darwin/i386/x86_64/ARM and iPhoneSimulator/i386/x86_64

Default debug format for Darwin/i386

MacOSAll unit: changed parameter and opaque types

Windows 9x series

Windows 9x series unsupported

Windows/x86_64

Exception handling has been changed to be ABI-conformant

winwidestringalloc has been deprecated

WinCE

Define UNICODE was changed to FPC_OS_UNICODE

Other

Stabs support has been disabled for 64 bit targets

Previous release notes


From the Free Pascal wiki, page "User Changes 3.0", as it stood on 2020-03-01 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.