Re: [fpc-devel] Implicit function specialization precedence

2021-04-06 Thread Sven Barth via fpc-devel

Am 06.04.2021 um 23:11 schrieb Ryan Joseph via fpc-devel:



On Apr 6, 2021, at 12:57 PM, Sven Barth  wrote:

In the example you posted below, I agree with you, but that is not what I said. 
Look at my example again:

Also could you please verify that $H+ isn't causing problems? The string literal 'Hello 
World' is a short string but "String" is an AnsiString so that may influence 
the results you're expecting.  However  even without the operator I don't know how to 
delineate between the explicit cast vs the non-explicit cast.

Writeln(Test('Hello World'));
Writeln(Test(String('Hello World')));

These both appear to be equal as far as is_better_candidate is concerned.


First of *you* need to make sure that the type you pick for the generic 
parameter for a string constant is the correct one matching the $H+ 
directive as well as the UnicodeString modeswitch (and if the string 
constant contains WideChar elements it needs to be a UnicodeString 
anyway). That's where you currently search for the SHORTSTRING type.


Then you only need to make sure that the check for generic vs. 
non-generic is in place as I said in the other mail and the compiler 
will do the rest for you. You don't need to do *anything*. Your task is 
merely to provide the compiler with the suitable overload candidates and 
a way to check their order and it will already do all the rest.


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Implicit function specialization precedence

2021-04-06 Thread Sven Barth via fpc-devel

Am 06.04.2021 um 22:47 schrieb Ryan Joseph via fpc-devel:



On Apr 6, 2021, at 12:57 PM, Sven Barth  wrote:

In this specific case the two functions also are *not* ambigous, because for the 
non-generic Test the parameter requires an implicit conversion, but the implicit 
specialization does not. For example if there would be a "Test(aArg: LongInt)" 
instead of the generic the compiler would pick that instead of the string one. So if you 
move the check for generic vs. non-generic to the end of is_better_candidate all the 
other rules to determine this will take precedence.

So the root of the problem is that we have no way to choose the generic 
function via explicit casting? That makes sense and presumably I can use the 
final result of is_better_candidate to determine this?


You simply need to put your check for generic vs. not-generic after the 
check for ordinal_distance inside is_better_candidate instead of at the 
start of the function.



  In your example:

Writeln(Test('Hello World'));   // is_better_candidate res = -1
Writeln(Test(42));  // is_better_candidate 
res = 1
Writeln(Test(String(42)));  // is_better_candidate res = -1

I'm struggling to see how the operator influenced the result. Res is -1 in both 
cases so how do we know which Test we want to call?


The compiler is free to use implicit operator overloads when determining 
the overload to pick.


When the compiler sees the first call to Test it will have the 
non-generic Test(String) in its candidate list as well as 
Test(String) due to the implicit specialization. Here it will 
use the non-generic one.


In the second case the compiler will have the non-generic Test(String) 
due to the implicit operator as well as Test(LongInt) due to 
the implicit specialization. Here it will pick the generic one, because 
a call without a type conversion is considered better.


In the third case the will will contain Test(String) as well as 
Test(String) due to the parameter being explicitely casted to 
String with the compiler again picking the non-generic one.


Without the explicit cast by the user the compiler would have picked the 
Test, but using a cast to the type of non-generic function one 
is able to enforce the non-generic function (for example to avoid an 
error during specialization if the Test<> function would not be able to 
handle the LongInt type).


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Implicit function specialization precedence

2021-04-06 Thread Ryan Joseph via fpc-devel


> On Apr 6, 2021, at 12:57 PM, Sven Barth  wrote:
> 
> In the example you posted below, I agree with you, but that is not what I 
> said. Look at my example again:

Also could you please verify that $H+ isn't causing problems? The string 
literal 'Hello World' is a short string but "String" is an AnsiString so that 
may influence the results you're expecting.  However  even without the operator 
I don't know how to delineate between the explicit cast vs the non-explicit 
cast.

Writeln(Test('Hello World'));
Writeln(Test(String('Hello World')));

These both appear to be equal as far as is_better_candidate is concerned.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Implicit function specialization precedence

2021-04-06 Thread Ryan Joseph via fpc-devel


> On Apr 6, 2021, at 12:57 PM, Sven Barth  wrote:
> 
> In this specific case the two functions also are *not* ambigous, because for 
> the non-generic Test the parameter requires an implicit conversion, but the 
> implicit specialization does not. For example if there would be a "Test(aArg: 
> LongInt)" instead of the generic the compiler would pick that instead of the 
> string one. So if you move the check for generic vs. non-generic to the end 
> of is_better_candidate all the other rules to determine this will take 
> precedence.

So the root of the problem is that we have no way to choose the generic 
function via explicit casting? That makes sense and presumably I can use the 
final result of is_better_candidate to determine this? In your example:

Writeln(Test('Hello World'));   // is_better_candidate res = -1
Writeln(Test(42));  // is_better_candidate 
res = 1
Writeln(Test(String(42)));  // is_better_candidate res = -1

I'm struggling to see how the operator influenced the result. Res is -1 in both 
cases so how do we know which Test we want to call?

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Implicit function specialization precedence

2021-04-06 Thread Sven Barth via fpc-devel

Am 06.04.2021 um 17:45 schrieb Ryan Joseph via fpc-devel:

Finally some movement is happening on implicit function specialization and I'm 
almost finished now except some questions about precedence have been raised 
again. Initially I thought we decided on non-generic functions taking 
precedence in the case of *any* name collisions (the original thread 
https://lists.freepascal.org/pipermail/fpc-pascal/2018-December/055225.html) 
but Sven is saying now that this isn't the case (see the remarks on the bug 
report https://bugs.freepascal.org/view.php?id=35261). I'm asking this here not 
to go over Svens head but in hopes to get some answers quicker (it can take us 
weeks sometimes to round trip even simple questions).

Currently what I implemented is that in the case below non-generic Test() will take 
precedence even though Test could be specialized and indeed even comes 
after.  My questions:

1) What is required for Delphi compatibility? I never used Delphi and I thought 
we decided this initially for Delphi compatibility. Of course we can make a 
Delphi mode only option if we need to.

2) Svens final remarks on the bug tracker are "Right now your code will pick the existing String 
overload even if specializing the generic might be the better choice. If the user really wants the String 
one (or if the specializing the generic does not work) the user can still force the String overload by 
casting the parameter to a String.". I'm confused about this because Test(String) and 
Test are both identical and thus I don't see what is the "better choice".

Personally I feel like we should fallback to the non-generic function as a way to 
resolve ambiguity but I can also see why Test should take precedence simply 
because it comes after Test().


In the example you posted below, I agree with you, but that is not what 
I said. Look at my example again:


=== code begin ===

program timplicitspez;

{$mode objfpc}{$H+}
{$modeswitch IMPLICITFUNCTIONSPECIALIZATION}

function Test(const aStr: String): LongInt;
begin
  Result := 1;
end;

generic function Test(aT: T): LongInt;
begin
  Result := 2;
end;

operator := (aArg: LongInt): String;
begin
  { potentially expensive conversion }
  Result := '';
end;

begin
  Writeln(Test('Hello World'));
  Writeln(Test(42));
end.

=== code end ===

The important part here is the operator overload. If the generic 
function would not exist then the compiler would simply call the 
operator overload to convert the 42 to a String and call the function 
with the string overload. While in this example the conversion is 
essential a no-op in reality it might be more complex and expensive thus 
it might be better to use the implicit specialization of the 42 as is 
(in this case it would be a LongInt I think). Right now there is no 
possibility to enforce the use of the implicit specialization.


In this specific case the two functions also are *not* ambigous, because 
for the non-generic Test the parameter requires an implicit conversion, 
but the implicit specialization does not. For example if there would be 
a "Test(aArg: LongInt)" instead of the generic the compiler would pick 
that instead of the string one. So if you move the check for generic vs. 
non-generic to the end of is_better_candidate all the other rules to 
determine this will take precedence.


And to pick the non-generic one can do this in the above example: 
Test(String(42)), because here the type your implicit specialization 
code will receive will be String already and thus the generic vs. 
non-generic check will catch it and prefer the non-generic one.


Also Delphi agrees with me:

=== code begin ===

program timplspez;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TFoo = record
    f: LongInt;
    class operator Implicit(aArg: LongInt): TFoo;
  end;

  TTest = record
    class function Test(aArg: TFoo): LongInt; overload; static;
    class function Test(aArg: T): LongInt; overload; static;
  end;

class operator TFoo.Implicit(aArg: LongInt): TFoo;
begin
  Result.f := aArg;
end;

class function TTest.Test(aArg: TFoo): LongInt;
begin
  Result := 1;
end;

class function TTest.Test(aArg: T): LongInt;
begin
  Result := 2;
end;

var
  f: TFoo;
begin
  f := 21;
  Writeln(TTest.Test(f));
  Writeln(TTest.Test(42));
  Writeln(TTest.Test(TFoo(42)));
  Readln;
end.

=== code end ===

=== output begin ===

1
2
1

=== output end ===

This should answer both your points, cause they're related.

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Implicit function specialization precedence

2021-04-06 Thread Ryan Joseph via fpc-devel
Finally some movement is happening on implicit function specialization and I'm 
almost finished now except some questions about precedence have been raised 
again. Initially I thought we decided on non-generic functions taking 
precedence in the case of *any* name collisions (the original thread 
https://lists.freepascal.org/pipermail/fpc-pascal/2018-December/055225.html) 
but Sven is saying now that this isn't the case (see the remarks on the bug 
report https://bugs.freepascal.org/view.php?id=35261). I'm asking this here not 
to go over Svens head but in hopes to get some answers quicker (it can take us 
weeks sometimes to round trip even simple questions).

Currently what I implemented is that in the case below non-generic Test() will 
take precedence even though Test could be specialized and indeed even comes 
after.  My questions:

1) What is required for Delphi compatibility? I never used Delphi and I thought 
we decided this initially for Delphi compatibility. Of course we can make a 
Delphi mode only option if we need to.

2) Svens final remarks on the bug tracker are "Right now your code will pick 
the existing String overload even if specializing the generic might be the 
better choice. If the user really wants the String one (or if the specializing 
the generic does not work) the user can still force the String overload by 
casting the parameter to a String.". I'm confused about this because 
Test(String) and Test are both identical and thus I don't see what is 
the "better choice".

Personally I feel like we should fallback to the non-generic function as a way 
to resolve ambiguity but I can also see why Test should take precedence 
simply because it comes after Test().



{$mode objfpc}{$H+}
{$modeswitch IMPLICITFUNCTIONSPECIALIZATION}

function Test(const aStr: String): LongInt;
begin
  Result := 1;
end;

generic function Test(aT: T): LongInt;
begin
  Result := 2;
end;

begin
  Writeln(Test('Hello World'));
end.



And just to be clear even if the name is the same but parameters do not match 
the generic function will be selected. For example below Test will be 
specialized because Test() doesn't have a compatible signature.



function Test(const aStr: String): LongInt;
begin
  Result := 1;
end;

generic function Test(aT: T; aInt: Integer): LongInt;
begin
  Result := 2;
end;

begin
  Writeln(Test('Hello World', 1));// prints "2"
end.



Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Annoying error when building compiler on i386-win32

2021-04-06 Thread J. Gareth Moreton via fpc-devel
I'm trying to avoid removing the $linklib statement, but currently it's 
the only way to build the i386-win32 compiler on my 64-bit system.  I'm 
suggesting turning the error into a warning, if the correct DLL can't be 
found, because it doesn't affect successful compilation of the unit.


Of course, being able to locate the correct 32-bit DLL or some such is 
better overall, although I would still propose a warning over an error.


Gareth aka. Kit

On 06/04/2021 09:42, Michael Van Canneyt via fpc-devel wrote:



On Tue, 6 Apr 2021, Florian Klämpfl via fpc-devel wrote:




Am 06.04.2021 um 07:37 schrieb Sven Barth via fpc-devel 
:


Am 05.04.2021 um 20:33 schrieb J. Gareth Moreton via fpc-devel:

Hi everyone,

I have a slightly annoying error when building the compiler for 
i386-win32.  I mentioned it to Sven a while ago, and the cause is 
due to the fact that my copy of common.dll is 64-bit, not 32-bit 
(as Sven confirmed for me).


Compiling .\oracle\src\oraoci.pp
oraoci.pp(1437) Error: Invalid DLL C:\WINDOWS\system32\common.dll, 
invalid header size

oraoci.pp(1437) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted

Simply commenting out "{$linklib common}" on line 19 of the above 
file fixes the problem.  I would like to propose that this error be 
changed to a warning, since apparently not having the library 
present doesn't cause issues for compilation, just possibly 
execution later on.


No. If you have a messed up system, that is not *our* fault.


But isn’t the complaint valid to a certain degree: if one cross 
compiles from x86_64-win64 to i386-win32, then the wrong DLLs are 
checked due to folder redirection, no? We have only code in place for 
the other direction (i386-win32 to x86_64-win64).


The weird behaviour of windows is is not a valid reason to remove a 
{$linklib} statement.


Michael.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Annoying error when building compiler on i386-win32

2021-04-06 Thread Michael Van Canneyt via fpc-devel



On Tue, 6 Apr 2021, Florian Klämpfl via fpc-devel wrote:





Am 06.04.2021 um 10:42 schrieb Michael Van Canneyt via fpc-devel 
:



On Tue, 6 Apr 2021, Florian Klämpfl via fpc-devel wrote:





Am 06.04.2021 um 07:37 schrieb Sven Barth via fpc-devel 
:
Am 05.04.2021 um 20:33 schrieb J. Gareth Moreton via fpc-devel:

Hi everyone,
I have a slightly annoying error when building the compiler for i386-win32.  I 
mentioned it to Sven a while ago, and the cause is due to the fact that my copy 
of common.dll is 64-bit, not 32-bit (as Sven confirmed for me).
Compiling .\oracle\src\oraoci.pp
oraoci.pp(1437) Error: Invalid DLL C:\WINDOWS\system32\common.dll, invalid 
header size
oraoci.pp(1437) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Simply commenting out "{$linklib common}" on line 19 of the above file fixes 
the problem.  I would like to propose that this error be changed to a warning, since 
apparently not having the library present doesn't cause issues for compilation, just 
possibly execution later on.

No. If you have a messed up system, that is not *our* fault.


But isn’t the complaint valid to a certain degree: if one cross compiles from 
x86_64-win64 to i386-win32, then the wrong DLLs are checked due to folder 
redirection, no? We have only code in place for the other direction (i386-win32 
to x86_64-win64).


The weird behaviour of windows is is not a valid reason to remove a {$linklib} 
statement.


No. But the compiler could take care of the fact to look into the right 
directory as we do in the i386-win32 to x86_64-win64 case.


Absolutely.

Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Annoying error when building compiler on i386-win32

2021-04-06 Thread Florian Klämpfl via fpc-devel


> Am 06.04.2021 um 10:42 schrieb Michael Van Canneyt via fpc-devel 
> :
> 
> 
> 
> On Tue, 6 Apr 2021, Florian Klämpfl via fpc-devel wrote:
> 
>> 
>> 
>>> Am 06.04.2021 um 07:37 schrieb Sven Barth via fpc-devel 
>>> :
>>> Am 05.04.2021 um 20:33 schrieb J. Gareth Moreton via fpc-devel:
 Hi everyone,
 I have a slightly annoying error when building the compiler for 
 i386-win32.  I mentioned it to Sven a while ago, and the cause is due to 
 the fact that my copy of common.dll is 64-bit, not 32-bit (as Sven 
 confirmed for me).
 Compiling .\oracle\src\oraoci.pp
 oraoci.pp(1437) Error: Invalid DLL C:\WINDOWS\system32\common.dll, invalid 
 header size
 oraoci.pp(1437) Fatal: There were 1 errors compiling module, stopping
 Fatal: Compilation aborted
 Simply commenting out "{$linklib common}" on line 19 of the above file 
 fixes the problem.  I would like to propose that this error be changed to 
 a warning, since apparently not having the library present doesn't cause 
 issues for compilation, just possibly execution later on.
>>> No. If you have a messed up system, that is not *our* fault.
>> 
>> But isn’t the complaint valid to a certain degree: if one cross compiles 
>> from x86_64-win64 to i386-win32, then the wrong DLLs are checked due to 
>> folder redirection, no? We have only code in place for the other direction 
>> (i386-win32 to x86_64-win64).
> 
> The weird behaviour of windows is is not a valid reason to remove a 
> {$linklib} statement.

No. But the compiler could take care of the fact to look into the right 
directory as we do in the i386-win32 to x86_64-win64 case.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Annoying error when building compiler on i386-win32

2021-04-06 Thread Michael Van Canneyt via fpc-devel



On Tue, 6 Apr 2021, Florian Klämpfl via fpc-devel wrote:





Am 06.04.2021 um 07:37 schrieb Sven Barth via fpc-devel 
:

Am 05.04.2021 um 20:33 schrieb J. Gareth Moreton via fpc-devel:

Hi everyone,

I have a slightly annoying error when building the compiler for i386-win32.  I 
mentioned it to Sven a while ago, and the cause is due to the fact that my copy 
of common.dll is 64-bit, not 32-bit (as Sven confirmed for me).

Compiling .\oracle\src\oraoci.pp
oraoci.pp(1437) Error: Invalid DLL C:\WINDOWS\system32\common.dll, invalid 
header size
oraoci.pp(1437) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted

Simply commenting out "{$linklib common}" on line 19 of the above file fixes 
the problem.  I would like to propose that this error be changed to a warning, since 
apparently not having the library present doesn't cause issues for compilation, just 
possibly execution later on.


No. If you have a messed up system, that is not *our* fault.


But isn’t the complaint valid to a certain degree: if one cross compiles from 
x86_64-win64 to i386-win32, then the wrong DLLs are checked due to folder 
redirection, no? We have only code in place for the other direction (i386-win32 
to x86_64-win64).


The weird behaviour of windows is is not a valid reason to remove a {$linklib} 
statement.

Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Annoying error when building compiler on i386-win32

2021-04-06 Thread Florian Klämpfl via fpc-devel


> Am 06.04.2021 um 07:37 schrieb Sven Barth via fpc-devel 
> :
> 
> Am 05.04.2021 um 20:33 schrieb J. Gareth Moreton via fpc-devel:
>> Hi everyone,
>> 
>> I have a slightly annoying error when building the compiler for i386-win32.  
>> I mentioned it to Sven a while ago, and the cause is due to the fact that my 
>> copy of common.dll is 64-bit, not 32-bit (as Sven confirmed for me).
>> 
>> Compiling .\oracle\src\oraoci.pp
>> oraoci.pp(1437) Error: Invalid DLL C:\WINDOWS\system32\common.dll, invalid 
>> header size
>> oraoci.pp(1437) Fatal: There were 1 errors compiling module, stopping
>> Fatal: Compilation aborted
>> 
>> Simply commenting out "{$linklib common}" on line 19 of the above file fixes 
>> the problem.  I would like to propose that this error be changed to a 
>> warning, since apparently not having the library present doesn't cause 
>> issues for compilation, just possibly execution later on.
> 
> No. If you have a messed up system, that is not *our* fault.

But isn’t the complaint valid to a certain degree: if one cross compiles from 
x86_64-win64 to i386-win32, then the wrong DLLs are checked due to folder 
redirection, no? We have only code in place for the other direction (i386-win32 
to x86_64-win64).
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel