Re: [fpc-devel] Implicit function specialization precedence
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
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
> 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
> 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
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
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
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
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
> 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
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
> 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