Recent

Author Topic: Delphi, FPC discrepancy  (Read 4967 times)

440bx

  • Hero Member
  • *****
  • Posts: 6556
Delphi, FPC discrepancy
« on: November 01, 2021, 08:42:07 am »
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][+][-]
  1. {$APPTYPE       CONSOLE}
  2.  
  3. {$TYPEDADDRESS  ON}
  4.  
  5. {$LONGSTRINGS   OFF}
  6.  
  7. {$ifdef VER90}
  8.   {$define DELPHIv2}
  9. {$endif}
  10.  
  11. { --------------------------------------------------------------------------- }
  12.  
  13. program _IntToHex;
  14.   { program to test custom IntToHex                                           }
  15.  
  16. const
  17.   ntdll = 'ntdll';
  18.  
  19.  
  20. {$ifdef FPC}
  21.     function sprintf
  22.                (
  23.                 { _out_ } OutAsciizBuffer : pchar;
  24.                 { _in_  } InAsciizFormat  : pchar
  25.                 { ...   } { InArguments }
  26.                )
  27.              : integer; cdecl; varargs; external ntdll;            { !! CDECL }
  28. {$endif}
  29.  
  30. {$ifdef DELPHIv2}
  31. type
  32.   DWORD   = longint;
  33.   ptruint = DWORD;
  34. {$endif}
  35.  
  36.  
  37. { --------------------------------------------------------------------------- }
  38.  
  39. function ToHex(InValue  : ptruint;
  40.                InDigits : byte;
  41.                InPrefix : char;
  42.                OutHex   : pchar) : pchar;
  43. var
  44.   d : pchar;          { destination pointer                                   }
  45.  
  46. const
  47.   FORMAT32 = '%0*X';
  48.   FORMAT64 = '%0*llX';
  49.  
  50. {$ifdef DELPHIv2}
  51.   { FPC, unlike Delphi, does not accept an external declaration in a local scope }
  52.  
  53.   function sprintf
  54.              (
  55.               { _out_ } OutAsciizBuffer : pchar;
  56.               { _in_  } InAsciizFormat  : pchar;
  57.               { _in_  } InDigitCount    : DWORD;
  58.               { _in_  } InValue         : DWORD
  59.              )
  60.            : integer; cdecl; external ntdll;                       { !! CDECL }
  61. {$endif}
  62.  
  63. begin
  64.   result := OutHex;
  65.  
  66.   if result = nil then exit;
  67.  
  68.   d := OutHex;
  69.  
  70.   if InPrefix <> #0 then
  71.   begin
  72.    d^ := InPrefix;      { usually a '$' sign                                  }
  73.    inc(d);
  74.   end;
  75.  
  76.   sprintf(d,
  77.           {$ifdef WIN64} FORMAT64 {$endif} {$ifdef WIN32} FORMAT32 {$endif},
  78.           InDigits,
  79.           InValue);
  80. end;
  81.  
  82. { --------------------------------------------------------------------------- }
  83.  
  84. var
  85.   ValueU : ptruint = {$ifdef WIN64} high(qword) {$endif}
  86.                      {$ifdef WIN32} -1          {$endif};
  87.  
  88.   Buf    : packed array[0..255] of char;
  89.  
  90.  
  91. const
  92.   WIDTH  = 23;
  93.  
  94.  
  95. begin
  96.   writeln;
  97.   writeln;
  98.  
  99.   writeln('  Value : ', ValueU:WIDTH,
  100.           '  hexed : ' , ToHex(ValueU, 0, '$', Buf):WIDTH);
  101.  
  102.   ValueU := 5;
  103.   writeln('  Value : ', ValueU:WIDTH,
  104.           '  hexed : ' , ToHex(ValueU, 3, '$', Buf):WIDTH);
  105.  
  106.   writeln('  Value : ', ValueU:WIDTH,
  107.           '  hexed : ' , ToHex(ValueU, 3, #0, Buf):WIDTH);
  108.  
  109.   writeln;
  110.   writeln;
  111.   writeln('press ENTER/RETURN to end this program');
  112.   readln;
  113. end.
  114.  
Including {$MODE DELPHI} makes no difference.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12944
  • FPC developer.
Re: Delphi, FPC discrepancy
« Reply #1 on: November 01, 2021, 10:09:43 am »
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

  • Hero Member
  • *****
  • Posts: 6556
Re: Delphi, FPC discrepancy
« Reply #2 on: November 01, 2021, 10:23:22 am »
@marcov

Interesting... Delphi 2 has no problem with it and handles it correctly.

Just curious, did you try compiling the code I posted ?
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 19393
  • Glad to be alive.
Re: Delphi, FPC discrepancy
« Reply #3 on: November 01, 2021, 11:23:03 am »
This simply works:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}{$APPTYPE CONSOLE}
  2.  
  3. {$TYPEDADDRESS  ON}
  4.  
  5. {$LONGSTRINGS   OFF}
  6.  
  7. {$ifdef VER90}
  8.   {$define DELPHIv2}
  9. {$endif}
  10.  
  11. { --------------------------------------------------------------------------- }
  12.  
  13. program _IntToHex;
  14.   { program to test custom IntToHex                                           }
  15.  
  16. const
  17.   ntdll = 'ntdll';
  18.  
  19.  
  20. {$ifdef FPC}
  21.     function sprintf
  22.                (
  23.                 { _out_ } OutAsciizBuffer : pchar;
  24.                 { _in_  } InAsciizFormat  : pchar
  25.                 { ...   } { InArguments }
  26.                )
  27.              : integer; cdecl; varargs; external ntdll;            { !! CDECL }
  28. {$endif}
  29.  
  30. {$ifdef DELPHIv2}
  31. type
  32.   DWORD   = longint;
  33.   ptruint = DWORD;
  34. {$endif}
  35.  
  36.  
  37. { --------------------------------------------------------------------------- }
  38.  
  39. function ToHex(InValue  : ptruint;
  40.                InDigits : byte;
  41.                InPrefix : char;
  42.                OutHex   : pchar) : pchar;
  43. var
  44.   d : pchar;          { destination pointer                                   }
  45.  
  46. const
  47.   FORMAT32 = '%0*X';
  48.   FORMAT64 = '%0*llX';
  49.  
  50. {$ifdef DELPHIv2}
  51.   { FPC, unlike Delphi, does not accept an external declaration in a local scope }
  52.  
  53.   function sprintf
  54.              (
  55.               { _out_ } OutAsciizBuffer : pchar;
  56.               { _in_  } InAsciizFormat  : pchar;
  57.               { _in_  } InDigitCount    : DWORD;
  58.               { _in_  } InValue         : DWORD
  59.              )
  60.            : integer; cdecl; external ntdll;                       { !! CDECL }
  61. {$endif}
  62.  
  63. begin
  64.   result := OutHex;
  65.  
  66.   if result = nil then exit;
  67.  
  68.   d := OutHex;
  69.  
  70.   if InPrefix <> #0 then
  71.   begin
  72.    d^ := InPrefix;      { usually a '$' sign                                  }
  73.    inc(d);
  74.   end;
  75.  
  76.   sprintf(d,
  77.           {$ifdef WIN64} FORMAT64 {$endif} {$ifdef WIN32} FORMAT32 {$endif},
  78.           InDigits,
  79.           InValue);
  80. end;
  81.  
  82. { --------------------------------------------------------------------------- }
  83.  
  84. var
  85.   ValueU : ptruint = {$ifdef WIN64} high(qword) {$endif}
  86.                      {$ifdef WIN32} -1          {$endif};
  87.  
  88.   Buf    : packed array[0..255] of char;
  89.  
  90.  
  91. const
  92.   WIDTH  = 23;
  93.  
  94.  
  95. begin
  96.   writeln;
  97.   writeln;
  98.  
  99.   writeln('  Value : ', ValueU:WIDTH,
  100.           '  hexed : ' , ToHex(ValueU, 0, '$', Buf):WIDTH);
  101.  
  102.   ValueU := 5;
  103.   writeln('  Value : ', ValueU:WIDTH,
  104.           '  hexed : ' , ToHex(ValueU, 3, '$', Buf):WIDTH);
  105.  
  106.   writeln('  Value : ', ValueU:WIDTH,
  107.           '  hexed : ' , ToHex(ValueU, 3, #0, Buf):WIDTH);
  108.  
  109.   writeln;
  110.   writeln;
  111.   writeln('press ENTER/RETURN to end this program');
  112.   readln;
  113. 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.....
« Last Edit: November 01, 2021, 11:26:05 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

440bx

  • Hero Member
  • *****
  • Posts: 6556
Re: Delphi, FPC discrepancy
« Reply #4 on: November 01, 2021, 11:39:15 am »
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.)


FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12944
  • FPC developer.
Re: Delphi, FPC discrepancy
« Reply #5 on: November 01, 2021, 12:58:24 pm »
@marcov

Interesting... Delphi 2 has no problem with it and handles it correctly.

Overloading and varargs (Kylix,D6) might have effects on this too.

Just 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

  • Full Member
  • ***
  • Posts: 144
Re: Delphi, FPC discrepancy
« Reply #6 on: November 01, 2021, 01:03:17 pm »
Delphi 2 was the first 32 bit Delphi and the worst. Don't use it.

440bx

  • Hero Member
  • *****
  • Posts: 6556
Re: Delphi, FPC discrepancy
« Reply #7 on: November 01, 2021, 01:08:19 pm »
I 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.



Delphi 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.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1225
    • Burdjia
Re: Delphi, FPC discrepancy
« Reply #8 on: November 01, 2021, 01:23:37 pm »
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.
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

440bx

  • Hero Member
  • *****
  • Posts: 6556
Re: Delphi, FPC discrepancy
« Reply #9 on: November 01, 2021, 01:36:00 pm »
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).
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.

Also, 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.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12944
  • FPC developer.
Re: Delphi, FPC discrepancy
« Reply #10 on: November 01, 2021, 01:37:31 pm »
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

  • Hero Member
  • *****
  • Posts: 2510
Re: Delphi, FPC discrepancy
« Reply #11 on: November 01, 2021, 07:26:18 pm »
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'
The same from Delphi 7:
Quote
[Error] Project2.dpr(60): Invalid compiler directive: 'EXTERNAL'

 

TinyPortal © 2005-2018