Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/Delphi/Language/Overloading/Global    [ Add a report in this area ]  
Report #:  86984   Status: Open
Ambiguous overloaded call error breaks existing code
Project:  Delphi Build #:  15.0.3890.34076
Version:    15.0 Submitted By:   Mattias Andersson
Report Type:  Suggestion / Enhancement Request Date Reported:  8/6/2010 6:49:57 AM
Severity:    Commonly encountered problem Last Updated: 5/20/2012 5:22:08 AM
Platform:    All platforms Internal Tracking #:   279357
Resolution: None (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: (1 Total Rating)
5.00 out of 5
Total Votes: 15
Description
(1) In the Delphi help, the following rule describes how ambiguities are resolved when two or more units declare the same identifiers:

If two or more units declare the same identifier in their interface
sections, an unqualified reference to the identifier selects the
declaration in the innermost scope, that is, in the unit where the
reference itself occurs, or, if that unit does not declare the
identifier, in the last unit in the uses  clause that does declare the
identifier.

(from section "Naming Conflicts"
http://docwiki.embarcadero.com/RADStudio/XE/en/Declarations_and_Statements)

(2) The following rule describes how ambiguities are resolved when there are two or more assignment-compatible overloaded routines:

You can pass to an overloaded routine parameters that are not identical
in type with those in any of the routine's declarations, but that are
assignment-compatible with the parameters in more than one declaration.
This happens most frequently when a routine is overloaded with
different integer types or different real types - for example:

procedure Store(X: Longint); overload;
procedure Store(X: Shortint); overload;

In these cases, when it is possible to do so without ambiguity, the
compiler invokes the routine whose parameters are of the type with the
smallest range that accommodates the actual parameters in the call.
(Remember that real-valued constant expressions are always of type
Extended.)

(see section "Overloading Procedures and Functions"
http://docwiki.embarcadero.com/RADStudio/XE/en/Procedures_and_Functions)

However, (2) will fail with the error "ambiguous overloaded call", if it's not possible to resolve the ambiguity between two overloaded routines (see Steps). The only way to resolve this would be to add a unit qualifier that determines which one to invoke. This is a problem, because it invalidates the rule described by (1) in this very special case. For instance, if you implement your own overloaded Floor and Ceil routines and put them in a unit called Math2 and if you include both Math and Math2 in the uses clause of a third unit, then you need to use a unit qualifier to each and every call to either Floor or Ceil. I think instead of breaking perfectly valid code with the "ambiguous overloaded call" error, one should use the name conflict resolution scheme described by (1) in this case.

Steps to Reproduce:
unit A;

interface

procedure Dummy; overload;

[...]

--------------------------------------------------
unit B;

procedure Dummy; overload;

[...]

--------------------------------------------------
unit C;

interface

implementation

uses A, B;

procedure X;
begin
  A.Dummy;      // no error
  B.Dummy;      // no error
  Dummy;        // Error: Ambiguous overloaded call
end;

end.
Workarounds
None
Attachment
None
Comments

None

Server Response from: ETNACODE01