Delphi, FPC discrepancy lazarus / 62-General ---------------------------------------------------------------------- 440bx · 2021-11-01 07:42 Hello, Delphi (version 2) accepts a definition of an external function in a local scope while FPC refuses it. The following test program compiles and runs with Delphi but, does not compile with FPC if the declaration in the ToHex function is not restricted to Delphi:Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$APPTYPE       CONSOLE} {$TYPEDADDRESS  ON} {$LONGSTRINGS   OFF} {$ifdef VER90}  {$define DELPHIv2}{$endif} { -------------------- ------------------------------------------------------- } program _IntToHex;  { program to test custom IntToHex                                         } const  ntdll = 'ntdll';  {$ifdef FPC}    function sprintf               (                { _out_ } OutAsciizBuffer : pchar;                { _in_  } InAsciizFormat  : pchar              { ...   } { InArguments }               )             : integer; cdecl; varargs; external ntdll;            { !! CDECL }{$endif} {$ifdef DELPHIv2}type  DWORD   = longint;  ptruint = DWORD;{$endif}  { ---------------------------------------------------- ----------------------- } function ToHex(InValue  : ptruint;             InDigits : byte;               InPrefix : char;               OutHex   : pchar) : pchar;var  d : pchar;          { destination pointer                                   } const  FORMAT32 = '%0*X';  FORMAT64 = '%0*llX'; {$ifdef DELPHIv2}  { FPC, unlike Delphi, does not accept an external declaration in a local scope }   function sprintf           (              { _out_ } OutAsciizBuffer : pchar;            { _in_  } InAsciizFormat  : pchar;              { _in_  } InDigitCount    : DWORD;              { _in_  } InValue         : DWORD             )           : integer; cdecl; external ntdll;                     { !! CDECL }{$endif} begin  result := OutHex;   if result = nil then exit;   d := OutHex;   if InPrefix <> #0 then  begin   d^ := InPrefix;      { usually a '$' sign                                }   inc(d);  end;   sprintf(d,          {$ifdef WIN64} FORMAT64 {$endif} {$ifdef WIN32} FORMAT32 {$endif},          InDigits,          InValue);end; { ----------------------------------- ---------------------------------------- } var  ValueU : ptruint = {$ifdef WIN64} high(qword) {$endif}                     {$ifdef WIN32} -1          {$endif};   Buf    : packed array[0..255] of char;  const  WIDTH  = 23;  begin  writeln;  writeln;   writeln('  Value : ', ValueU:WIDTH,          '  hexed : ' , ToHex(ValueU, 0, '$', Buf):WIDTH);   ValueU := 5;  writeln('  Value : ', ValueU:WIDTH,        '  hexed : ' , ToHex(ValueU, 3, '$', Buf):WIDTH);   writeln('  Value : ', ValueU:WIDTH,          '  hexed : ' , ToHex(ValueU, 3, #0, Buf):WIDTH);   writeln;  writeln;  writeln('press ENTER/RETURN to end this program');  readln;end. Including {$MODE DELPHI} makes no difference. ---------------------------------------------------------------------- marcov · 2021-11-01 09:09 Delphi Seattle gives an error if I try it (both in procedure as method scope). Quote[dcc32 Error] carriagecustomfrm.pas(988): E1030 Invalid compiler directive: 'EXTERNAL' ---------------------------------------------------------------------- 440bx · 2021-11-01 09:23 @marcov Interesting... Delphi 2 has no problem with it and handles it correctly. Just curious, did you try compiling the code I posted ? ---------------------------------------------------------------------- Thaddy · 2021-11-01 10:23 This simply works:Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$mode delphi}{$APPTYPE CONSOLE} {$TYPEDADDRESS  ON} {$LONGSTRINGS   OFF} {$ifdef VER90}  {$define DELPHIv2}{$endif} { ---------------------------------------------------------------------- ----- } program _IntToHex;  { program to test custom IntToHex                                         } const  ntdll = 'ntdll';  {$ifdef FPC}    function sprintf               (                { _out_ } OutAsciizBuffer : pchar;                { _in_  } InAsciizFormat  : pchar                { ...   } { InArguments }               )           : integer; cdecl; varargs; external ntdll;            { !! CDECL }{$endif} {$ifdef DELPHIv2}type  DWORD   = longint;  ptruint = DWORD;{$endif}  { ---------------------------------------------------- ----------------------- } function ToHex(InValue  : ptruint;             InDigits : byte;               InPrefix : char;               OutHex   : pchar) : pchar;var  d : pchar;          { destination pointer                                   } const  FORMAT32 = '%0*X';  FORMAT64 = '%0*llX'; {$ifdef DELPHIv2}  { FPC, unlike Delphi, does not accept an external declaration in a local scope }   function sprintf           (              { _out_ } OutAsciizBuffer : pchar;            { _in_  } InAsciizFormat  : pchar;              { _in_  } InDigitCount    : DWORD;              { _in_  } InValue         : DWORD             )           : integer; cdecl; external ntdll;                     { !! CDECL }{$endif} begin  result := OutHex;   if result = nil then exit;   d := OutHex;   if InPrefix <> #0 then  begin   d^ := InPrefix;      { usually a '$' sign                                }   inc(d);  end;   sprintf(d,          {$ifdef WIN64} FORMAT64 {$endif} {$ifdef WIN32} FORMAT32 {$endif},          InDigits,          InValue);end; { ----------------------------------- ---------------------------------------- } var  ValueU : ptruint = {$ifdef WIN64} high(qword) {$endif}                     {$ifdef WIN32} -1          {$endif};   Buf    : packed array[0..255] of char;  const  WIDTH  = 23;  begin  writeln;  writeln;   writeln('  Value : ', ValueU:WIDTH,          '  hexed : ' , ToHex(ValueU, 0, '$', Buf):WIDTH);   ValueU := 5;  writeln('  Value : ', ValueU:WIDTH,        '  hexed : ' , ToHex(ValueU, 3, '$', Buf):WIDTH);   writeln('  Value : ', ValueU:WIDTH,          '  hexed : ' , ToHex(ValueU, 3, #0, Buf):WIDTH);   writeln;  writeln;  writeln('press ENTER/RETURN to end this program');  readln;end.I was too lazy to adapt the formatting...(I alreaddy need glasses and this hurts my eyes even more) Also note D2 can never be a benchmark. Almost every Delphi version after that does not comply with D2 syntax..... ---------------------------------------------------------------------- 440bx · 2021-11-01 10:39 to see the problem in FPC, lines 50 and 61 (in the code you posted) need to be commented out.  FPC won't accept it, Delphi 2 is fine with it. As far as Delphi 2 not being a benchmark, there are a few things I can say on its behalf, among them, it's less bloated than any subsequent version of Delphi, its debug symbols are understood by SoftICE which enables writing some really devilish code... on today's machines its compile speed is unbelievable (On rare occasions I have seen it compile a little over half a million lines of code in just a hair above one (1) second... if I had not seen it, I'd have a hard time believing it... and that's on an _old_ 2.8ghz i860 machine, running in a VM with mechanical hard drives)  Over 200,000 lines per second is common. Unfortunately, when it comes to anything in 64 bits, it is completely inadequate but for 32 bits, it still does very well (function overloading would be really nice to have though.) ---------------------------------------------------------------------- marcov · 2021-11-01 11:58 Quote from: 440bx on November 01, 2021, 10:23:22 am@marcov Interesting... Delphi 2 has no problem with it and handles it correctly. Overloading and varargs (Kylix,D6) might have effects on this too. Quote from: 440bx on November 01, 2021, 10:23:22 amJust curious, did you try compiling the code I posted ? No, I just tried to insert the function in the code I was working with. I now create a new project with your verbatim code, commented both delphi defines, but still same errormessage. ---------------------------------------------------------------------- stocki · 2021-11-01 12:03 Delphi 2 was the first 32 bit Delphi and the worst. Don't use it. ---------------------------------------------------------------------- 440bx · 2021-11-01 12:08 Quote from: marcov on November 01, 2021, 12:58:24 pmI now create a new project with your verbatim code, commented both delphi defines, but still same errormessage. I guess they changed that at some point in time. Quote from: stocki on November 01, 2021, 01:03:17 pmDelphi 2 was the first 32 bit Delphi and the worst. Don't use it. It's missing a few features I'd like to have but, I still think it's best version of Delphi. ---------------------------------------------------------------------- Ñuño_Martínez · 2021-11-01 12:23 I came juts to say the same thing than stocki.  I actually don't know if it's the worst but it isn't the best (Delphi 6 is way better, and I've read a lot of people think the best was Delphi 7). Also, from my experience, it is hard (if not just impossible) write code that works with FPC and anything older than Delphi 7. ---------------------------------------------------------------------- 440bx · 2021-11-01 12:36 Quote from: Ñuño_Martínez on November 01, 2021, 01:23:37 pmI came juts to say the same thing than stocki.  I actually don't know if it's the worst but it isn't the best (Delphi 6 is way better, and I've read a lot of people think the best was Delphi 7). I have a copy of Delphi 5, which I purchased because it had some support for 64 bit integer operations.  I used it for about 2 months and went back to Delphi 2. Quote from: Ñuño_Martínez on November 01, 2021, 01:23:37 pmAlso, from my experience, it is hard (if not just impossible) write code that works with FPC and anything older than Delphi 7. As long as the application doesn't need to deal with 64 bit operations, I routinely write code that works with FPC and Delphi 2 with very few {$ifdef ... } to account for differences. ---------------------------------------------------------------------- marcov · 2021-11-01 12:37 Personally, I favour XE7+ for use with FPC: - D2005/6: inlining,overloading - D2009   : {$pointermath on}, means easier porting of $mode objfpc pointer code. - DXE7+  : generics mostly debugged. Of course string support is a problem with D2009, but my applications are mostly not string processing heavy. ---------------------------------------------------------------------- ASerge · 2021-11-01 18:26 Quote from: marcov on November 01, 2021, 10:09:43 amDelphi Seattle gives an error if I try it (both in procedure as method scope). Quote[dcc32 Error] carriagecustomfrm.pas(988): E1030 Invalid compiler directive: 'EXTERNAL'The same from Delphi 7: Quote[Error] Project2.dpr(60): Invalid compiler directive: 'EXTERNAL'