• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 246
  • Last Modified:

duplicate functions in units

I am using Delphi 5

Hopefully this is an easy one and probably just a fundamental problem with my understanding of duplicated functions in units and "uses"

My understanding is that if you have two units that have the same function name, then the function in the last unit in your uses clause "wins"

For example, both units a.pas and b.pas have a min() function. If the uses clause was:

Uses a,b;

Then I would expect the min() function in unit b.pas to be used.

This appears to be the behavior I have experienced ever since using Delphi. However, I just recently added a new unit at the very beginning of my uses clause. I added this unit because I needed to use one of the functions it contains. This unit has many functions, one of which is the Min() function.

When I try to compile my program I get an error because my use of the min() function has invalid syntax. This is because I am using the syntax of the min() function from  the standard Delphi "math" unit. The error *appears* to be happening because the compiler is picking up the min() function from my new unit. The "math" unit has been placed *after* my new unit in the uses clause, so I can't understand why the compiler is using the min() function from the new unit.

I can (and have) fixed the problem by prefixing the function with the required unit as in "math.min()"

However, my big worry now is that other functions in this new unit (there are many) may be used that have the same name as other functions I am using in my program. As the compiler has not picked up any errors, the syntax of the functions must be the same. However, I am worried there could be subtle logic differences if the functions in the new unit are used instead of the existing ones.

So is my understanding of how duplicated functions in units are resolved correct?

Is there some exception that I am overlooking that some how means the fist unit in the uses clause "wins" when it comes to function name duplication

Thanks



0
clyde99
Asked:
clyde99
  • 5
  • 5
1 Solution
 
ThievingSixCommented:
Yes, when using functions of the same name you should prefix the function when called with the unit name. Relying on the position of the unit in the uses clause shouldn't be taken for granted.
0
 
clyde99Author Commented:
I have been using delphi 5 for nearly 8 years now. What I can't understand is why I have never seen this before

"Relying on the position of the unit in the uses clause shouldn't be taken for granted"

This would now *appear* to be the case, but do you have any concrete Boland reference to this fact.

The unit I have added has hundreds of functions. This would mean I would have to check every function for a duplicate name, and then change all the duplicates throughout the whole application to prefix by the required unit.

This just doesn't seem right to me
0
 
Geert GruwezOracle dbaCommented:
actually the best thing would be to rename your functions
it is a bit of work but it overcomes the problem

indeed the order shouldn't be taken for granted
but in 95% of the times it does work.
depending on what function you want you set that unit last

this is also how subclassing works

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
clyde99Author Commented:
OK I think I have worked out the problem, as I should have looked at the error more closely.

The actual compile error was: "Ambiguous overload call to 'min'"

So I am still of the opinon that functions are resloved in the order I first mentioned in my post 100% of the time.

However, what is happening here is that both units have overloaded versions of this function and some of these overloads conflict.

What I have learned from this is that when a function is more than one unit, the second takes precedence.

However, if there are oveloaded functions that are not the same then those overloaded functions in the first unit are still visible to the application. Further more, these visible overloaded functions can thus case a contention and throw the "Ambiguous overload call 'min'"

So providing you have the correct order in your uses clause it would appear you only need to qualify the unit if there are different overloaded functions with the same name that can cause a conflict.


 

0
 
Geert GruwezOracle dbaCommented:
ThievingSix provided the unambiguous correct and ultimate answer in prefixing the functions with the unit name !!!

next best thing is to rename the function

or you could try and figure out what order to set the units to get it working.

>>clyde99
What I have learned from this is that when a function is more than one unit, the second takes precedence.
-->no, the last unit in the list gets precedence and then working back to the first
0
 
clyde99Author Commented:
The issue I have with all the expert answers is that they keep saying that the order can not be taken for granted, and that I should qualify all  my dulicate functions or use other work arounds.

I dispute the assertion that you can't 100% rely on the order of the units declared in the uses clause.

That is, I believe that you can rely 100% in the order of your uses clause, and the last unit used always wins when there are duplicated functions.

If you place your units in the correct order then the only time you categorically need to qualify your duplicate functions is when they are overloaded, and the two units contain ambiguous overloads.

OK, there may a time when you want to use one duplicated function in the first unit, but the other duplicated in the second. In this case you would need to qualify the function in the first unit. However, this did not apply to my original question.

If an expert can provide evidence or link to a borland reference that disputes my assertion (that the last declared unit *always* wins when there are duplicate function names) then I would be happy to award points to that expert.
0
 
Geert GruwezOracle dbaCommented:
your assertion was the second unit, not the last
you should also think about different delphi versions
i found Delphi 2007 had odd behaviours toward this and the only way i got it to work was with prefix unitname

in this sample the order of the units has to be 1 way for 1 function
and an other way for a 2nd function in those same units

so the only way to get it 100% working is with prefix unitname
or rename the functions

you want prove ? fine, using below snippet
what is the correct order for the units,
if i want the panel1.Caption = 'App is running'
and Panel2.Caption = 'Wild guess !';

you don't need a borland reference to prove anything,
the reference is just by another programmer who can just as easily make mistakes


unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;
 
type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    procedure FormCreate(Sender: TObject);
  private
  public
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
uses Unit2, Unit3;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Panel1.Caption := Test_X + Test_Y;
  Panel2.Caption := Test_A + Test_B;
end;
 
unit Unit2;
 
interface
 
function Test_A: string;
function Test_B: string;
function Test_X: string;
function Test_Y: string;
 
implementation
 
function Test_A: string;
begin
  Result := 'Wild';
end;
 
function Test_B: string;
begin
  Result := ' guess !';
end;
 
function Test_X: string;
begin
  Result := 'no ';
end;
 
function Test_Y: string;
begin
  Result := 'no ';
end;
 
end.
 
unit Unit3;
 
interface
 
function Test_A: string;
function Test_B: string;
function Test_X: string;
function Test_Y: string;
 
implementation
 
function Test_A: string;
begin
  Result := 'missed';
end;
 
function Test_B: string;
begin
  Result := 'missed';
end;
 
function Test_X: string;
begin
  Result := 'App';
end;
 
function Test_Y: string;
begin
  Result := ' is running';
end;
 
end.

Open in new window

0
 
clyde99Author Commented:
>your assertion was the second unit, not the last

Huh? In my example the second *is* the last. Besides, read my original post. I categorigcally said last there.

>you should also think about different delphi versions

Well, I am not interested in other version. I am using Delphi5  as specified in my original post

>you want prove ? fine, using below snippet

That doesn't seem to prove anything new, and is not applicable to the explanation of my particular problem. I already made mention of this possible scenario in my previous post (see my paragraph starting with "OK, there may be a time...")
0
 
Geert GruwezOracle dbaCommented:
>>That is, I believe that you can rely 100% in the order of your uses clause
this is what i proved was not possible

i give up
0
 
clyde99Author Commented:
>this is what i proved was not possible

No, I don't accept that you did prove it at all.

What I am saying is that if the function name is duplicated then the function that will be used  in your program will always be the function name that is in your last unit in your uses clause. I assert this to always be the case in Delphi 5 and you can write your programs knowing that you can rely upon this behaviour.

However, the function used in the last unit  may well not be the function you *want* to use in order to give the correct result (which is what you have proved). In that case, then yes, you will need to qualify your function with the unit of the function name you want to use.  

I believe the correct answer to my original question should have gone something like:

"Yes, you can rely upon the order of your uses clause for the resolution of functions and this behaviour will always be consistent. Take a closer look at the error message to see if you can provide more information for your particular problem".
0
 
Geert GruwezOracle dbaCommented:
you probably don't know this:
a unit gets compiled in 2 passes,
first pass: the interface section,
second pass: the implementation section
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 5
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now