Почему вызов функции с одинаковыми сигнатурами в разных единицах не приводит к ошибке компилятора?
Почему этот код не приводит к ошибке компилятора? Я бы ожидал ошибку, например, "неоднозначный вызов"CallMe"". Это ошибка в компиляторе или в языке? Это можно обойти, используя имя устройства и точку перед вызовом функции, но это не защищает код пользователя и библиотечный код от коллизий имен. Вы думаете, что ваш код что-то сделал, но он сделал что-то другое, и это плохо.
uses
Unit2, Unit3;
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(CallMe(5)));
end;
unit Unit2;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
function CallMe(A: Integer) : Integer;
implementation
function CallMe(A: Integer) : Integer;
begin
Result := A * 2;
end;
end.
unit Unit3;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
function CallMe(A: Integer) : Integer;
implementation
function CallMe(A: Integer) : Integer;
begin
Result := A * -1;
end;
end.
2 ответа
Из документации:
Если два модуля объявляют переменную, константу, тип, процедуру или функцию с одинаковым именем, компилятор использует тот из модуля, который указан последним в предложении использования. (Чтобы получить доступ к идентификатору из другого модуля, вам необходимо добавить квалификатор: UnitName.Identifier.)
Как уже было сказано, компилятор загружает символы из модулей с использованием подхода, основанного на стеке, и анализирует стек от последней загруженной к первой загруженной для поиска символа. Хотя состояние препроцессора напрямую объединено с глобальным состоянием.
Перегрузка между узлами является исключением, хотя. Если вы пометите обе функции с перегрузкой; директива, вы получаете ошибку (бла было названием функции в тесте)
[dcc32 Error] test.dpr: E2251 Ambiguous overloaded call to 'bla'
Unit1.pas(8): Related method: procedure bla;
Unit2.pas(8): Related method: procedure bla;
если у вас есть две разные подписи, он выберет самую подходящую.
перекрестная перегрузка - более новая функция, но я точно не помню, когда. Я думаю, D2006.