Recent

Author Topic: No warning from FPC with ambiguous overload  (Read 1509 times)

WooBean

  • Full Member
  • ***
  • Posts: 112
Re: No warning from FPC with ambiguous overload
« Reply #15 on: April 12, 2021, 11:57:45 am »
@440bx

Quote
Specifically, if the format specifier had been "%S" instead of "%s", your change would result in the call not producing the correct result.

You must be kidding - do you really think that FPC compiler Team will ever study internal (Windows API) formatting switches to decide which version of overloaded function is the needed one?

@MarkMLI
Quote
The functions and parameters are entirely proper, and are accepted by the compiler without error, warning or other comment. That's the whole point of the thread.

If parameters of function were properly prepared you would have no problems to call the needed one version. Try to compile and execute  a little changed by me your example.
 :)   

 
Win7/64, Lazarus 2.0.8 win64-win64, FPC 3.0.4

440bx

  • Hero Member
  • *****
  • Posts: 2304
Re: No warning from FPC with ambiguous overload
« Reply #16 on: April 12, 2021, 01:00:13 pm »
@440bx

You must be kidding - do you really think that FPC compiler Team will ever study internal (Windows API) formatting switches to decide which version of overloaded function is the needed one?
No, I am not kidding.  That is precisely the point, the compiler cannot know what the correct overload is without inspecting the format specifier and it is completely unreasonable to expect the compiler to inspect the format specifier.  The result is, the compiler cannot know whether it should pass a widechar or char string and, since it doesn't know, if it decides on one of them, it should inform the programmer of its guess (sometimes euphemistically referred to as "preference") because that guess has about a 50% chance of being wrong, which for a compiler is pretty bad.

Just imagine, your code is logically perfect but you have only a 50% chance that what the compiler produces reflects what you coded and gives you no indication of the gamble it just handed you.  No hint or warning either to make it more interesting.  Even casinos give you a pamphlet (a hint/warning that the odds are not in your favor), the least a compiler should do is give a hint that code might not be in Kansas anymore.


FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

WooBean

  • Full Member
  • ***
  • Posts: 112
Re: No warning from FPC with ambiguous overload
« Reply #17 on: April 12, 2021, 01:27:12 pm »
@440bx, @MarkMLI

A working code tells enaugh (compile and execute the code below):
Code: Pascal  [Select][+][-]
  1. program project3;
  2.  
  3. uses
  4.   stupidUnit;
  5.  
  6. var
  7.   WideChars: wideString;
  8. begin
  9.   WideChars:='Hello unicode world!';
  10.   writeln(stupid1(pWideChar(@WideChars[1])));
  11.   writeln(stupid1('ABCD'));
  12.   readln;
  13. end.
  14.  

[edited]
Output is:
called with pWideChar
called with pChar


Code: Pascal  [Select][+][-]
  1. unit stupidUnit;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6. function stupid1(p:pWideChar):string; overload;
  7. function stupid1(p:pChar):string; overload;
  8.  
  9.  
  10.  
  11. implementation
  12. uses
  13.   Classes, SysUtils;
  14.  
  15. function stupid1(p:pWideChar):string; overload;
  16. begin
  17.   if p<>nil then  result:='called with pWideChar' else
  18.     result:='called with pWideChar(nil)';
  19.  
  20. end;
  21. function stupid1(p:pChar):string; overload;
  22. begin
  23.     if p<>nil then  result:='called with pChar' else
  24.     result:='called with pChar(nil)';
  25. end;
  26.  
  27.  
  28. end.  
  29.  

WooBean
 ;) ;)
 
« Last Edit: April 12, 2021, 01:40:44 pm by WooBean »
Win7/64, Lazarus 2.0.8 win64-win64, FPC 3.0.4

MarkMLl

  • Hero Member
  • *****
  • Posts: 2504
Re: No warning from FPC with ambiguous overload
« Reply #18 on: April 12, 2021, 01:31:46 pm »
@WooBean: which of those is chosen? Why is it chosen? Can you guarantee that? Because one of the senior compiler team wouldn't be drawn beyond saying that it was implementation-defined.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

y.ivanov

  • Jr. Member
  • **
  • Posts: 98
Re: No warning from FPC with ambiguous overload
« Reply #19 on: April 12, 2021, 01:40:55 pm »
IMHO, the compiler should not be blamed for having difficulties interpreting an ambiguous statements. Overloaded subroutines can be the  source of big frustration both for the compiler and the programmer. Ask somebody with at least a modest experience in C++ :)

@440bx
Isn't it better that way:
Code: Pascal  [Select][+][-]
  1. function swprintf_wc({ _out_ } OutWideBuffer    : pwidechar;
  2.                   { _in_  } InFormatString   : pwidechar;
  3.                   { _in_  } InWidechars      : pwidechar)
  4.          : integer; cdecl; external ntdll name 'swprintf';
  5. function swprintf_c({ _out_ } OutWideBuffer    : pwidechar;
  6.                   { _in_  } InFormatString   : pwidechar;
  7.                   { _in_  } InAnsiChars      : pchar)
  8.          : integer; cdecl; external ntdll name 'swprintf';
  9.  

BTW, It is more related to the functions of varargs than to overloaded ones, IMO they are mainly C language prerogative.

Regards,

WooBean

  • Full Member
  • ***
  • Posts: 112
Re: No warning from FPC with ambiguous overload
« Reply #20 on: April 12, 2021, 01:47:49 pm »
@WooBean: which of those is chosen? Why is it chosen? Can you guarantee that? Because one of the senior compiler team wouldn't be drawn beyond saying that it was implementation-defined.

MarkMLl

I see you are too busy to compile several lines example ... .
Output of my example is

called with pWideChar
called with pChar


FPC has no hesitation which overloaded version to choose.

WooBean
 :D
Win7/64, Lazarus 2.0.8 win64-win64, FPC 3.0.4

MarkMLl

  • Hero Member
  • *****
  • Posts: 2504
Re: No warning from FPC with ambiguous overload
« Reply #21 on: April 12, 2021, 02:18:25 pm »
I see you are too busy to compile several lines example ... .

Yes, I am busy frankly.

And you have no understanding of what "implementation defined" implies. I'm afraid that using coloured text and no doubt the occasional cat video is no substitute.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

440bx

  • Hero Member
  • *****
  • Posts: 2304
Re: No warning from FPC with ambiguous overload
« Reply #22 on: April 12, 2021, 07:51:27 pm »
IMHO, the compiler should not be blamed for having difficulties interpreting an ambiguous statements. Overloaded subroutines can be the  source of big frustration both for the compiler and the programmer. Ask somebody with at least a modest experience in C++ :)

@440bx
Isn't it better that way:
Code: Pascal  [Select][+][-]
  1. function swprintf_wc({ _out_ } OutWideBuffer    : pwidechar;
  2.                   { _in_  } InFormatString   : pwidechar;
  3.                   { _in_  } InWidechars      : pwidechar)
  4.          : integer; cdecl; external ntdll name 'swprintf';
  5. function swprintf_c({ _out_ } OutWideBuffer    : pwidechar;
  6.                   { _in_  } InFormatString   : pwidechar;
  7.                   { _in_  } InAnsiChars      : pchar)
  8.          : integer; cdecl; external ntdll name 'swprintf';
  9.  

BTW, It is more related to the functions of varargs than to overloaded ones, IMO they are mainly C language prerogative.

Regards,
The compiler isn't to blame for ambiguous statements.  What the compiler can legitimately be blamed for is making choices in situations that are not decidable and _not_ informing the programmer that it made an arbitrary choice that is not guaranteed in any way to be correct.  THAT is the problem, the compiler's silence when it made a decision that is simply arbitrary (calling it a "preference" doesn't change the situation.)

As far as the definitions you present, yes, of course it can be done that way but that's foregoes the compiler's abilities to overload definitions.  That's just a way of hiding the real problem which is, the compiler's failure to inform the programmer that it made an _arbitrary_ choice that may or may not be correct.



@Woobean

The problem is that the compiler doesn't tell you that a typecast is needed to get it right.  The compiler may make the wrong choice and not say anything to the programmer that it may have made an incorrect choice. 

Yes, you can typecast to get it right and, it would be much easier for the programmer to know a typecast is required to get it right if the compiler had the courtesy of pointing out that situation to the programmer.  That is problem, the lack of "courtesy" from the compiler.


FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

MarkMLl

  • Hero Member
  • *****
  • Posts: 2504
Re: No warning from FPC with ambiguous overload
« Reply #23 on: April 12, 2021, 10:05:37 pm »
The compiler isn't to blame for ambiguous statements.  What the compiler can legitimately be blamed for is making choices in situations that are not decidable and _not_ informing the programmer that it made an arbitrary choice that is not guaranteed in any way to be correct.  THAT is the problem, the compiler's silence when it made a decision that is simply arbitrary (calling it a "preference" doesn't change the situation.)

I'd add- and I'm not attempting to criticise anybody here- that when I was discussing this sort of thing with @PascalDragon a few days ago nobody said "that's inadvisable" or "that's abusing the language and/or compiler"... it was just accepted as something that could be done and wasn't too outrageous.

Again I'd emphasise that I am not trying to be critical. But having multiple functions/procedures/methods in this context does not appear to be an unreasonable thing to do.

But from the other thread, FPC's decision-making process appears to be consistent within the scope of a single compiler, but indeterminate when multiple implementations are considered. And thinking about it, should a user assume that it is determined by the order of declarations in the interface part (or object definiiton) or the order of implementation, since the compiler appears happy for these to differ? And what about forward declarations?

I think that everybody agrees that this is not an error situation. But it really does merit a note or warning.

MarkMLl

Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

ccrause

  • Sr. Member
  • ****
  • Posts: 375
Re: No warning from FPC with ambiguous overload
« Reply #24 on: April 13, 2021, 08:57:45 pm »
I think that everybody agrees that this is not an error situation. But it really does merit a note or warning.
I think there is merit in knowing what the compiler finds acceptable and what it finally chooses.  There is already some reporting build into the compiler around overload errors, so with a small tweak it is possible to get a list of feasible overloads followed by the specific overload chosen. Consider the following test case:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. procedure proc1(a: int8);
  4. begin
  5.   writeln(a);
  6. end;
  7.  
  8. procedure proc1(a: int16);
  9. begin
  10.   writeln(a);
  11. end;
  12.  
  13. procedure proc1(a: string);
  14. begin
  15.   writeln(a);
  16. end;
  17.  
  18. begin
  19.   proc1(111);
  20. end.

The overload report for this is:
Code: Text  [Select][+][-]
  1. text.inc(623,10) Hint: Found declaration: $fpc_get_output:^Text;
  2. project1.lpr(5,3) Hint: Overload $fpc_get_output:^Text; selected for call.
  3. text.inc(978,11) Hint: Found declaration: $fpc_write_text_sint(LongInt;var Text;Int64);
  4. project1.lpr(5,3) Hint: Overload $fpc_write_text_sint(LongInt;var Text;Int64); selected for call.
  5. text.inc(721,11) Hint: Found declaration: $fpc_writeln_end(var Text);
  6. project1.lpr(5,3) Hint: Overload $fpc_writeln_end(var Text); selected for call.
  7. text.inc(623,10) Hint: Found declaration: $fpc_get_output:^Text;
  8. project1.lpr(10,3) Hint: Overload $fpc_get_output:^Text; selected for call.
  9. text.inc(978,11) Hint: Found declaration: $fpc_write_text_sint(LongInt;var Text;Int64);
  10. project1.lpr(10,3) Hint: Overload $fpc_write_text_sint(LongInt;var Text;Int64); selected for call.
  11. text.inc(721,11) Hint: Found declaration: $fpc_writeln_end(var Text);
  12. project1.lpr(10,3) Hint: Overload $fpc_writeln_end(var Text); selected for call.
  13. text.inc(623,10) Hint: Found declaration: $fpc_get_output:^Text;
  14. project1.lpr(15,3) Hint: Overload $fpc_get_output:^Text; selected for call.
  15. text.inc(880,11) Hint: Found declaration: $fpc_write_text_ansistr(LongInt;var Text;const RawByteString);
  16. project1.lpr(15,3) Hint: Overload $fpc_write_text_ansistr(LongInt;var Text;const RawByteString); selected for call.
  17. text.inc(721,11) Hint: Found declaration: $fpc_writeln_end(var Text);
  18. project1.lpr(15,3) Hint: Overload $fpc_writeln_end(var Text); selected for call.
  19. project1.lpr(8,11) Hint: Found declaration: proc1(SmallInt);
  20. project1.lpr(3,11) Hint: Found declaration: proc1(ShortInt);
  21. project1.lpr(19,3) Hint: Overload proc1(ShortInt); selected for call.

The list of feasible overloads point to their respective declarations, so it is easy to jump to the code in Lazarus, while the selected declaration is printed with the call location. The phrasing of the hints probably need some work, and the sequence of information may not be intuitive, but it shows what can be reported. Obviously the amount of information can become quite large, so I'm thinking that it should be controlled with a local switch to limit the amount of information that e.g. calling into the RTL will generate.

The compiler branch if anyone wants to play around with this feature.

 

TinyPortal © 2005-2018