Ада разработка не происходит вообще - PullRequest
0 голосов
/ 21 февраля 2019

У меня необычная ситуация, когда код разработки просто не выполняется вообще.Это не проблема порядка разработки, а скорее проблема разработки.

Проблема в том, что я не "с" рассматриваемой единицей вообще, хотя в теории она все еще должна быть доступна, покапо мере его разработки.

Конечно, я мог бы просто добавить бесполезное «с» для рассматриваемой единицы, но в моем реальном случае использования есть большое количество единиц, с которыми мне пришлось бы это делать.

Мой вопрос: есть ли какой-либо способ в коде, через прагмы, в файле проекта gpr или через переключатели командной строки, которые я мог бы заставить компилятор включить файл, даже если он считает, что файлнет ссылки?

Вот минимальный рабочий пример:

as.ads:

package As is
    type A is tagged null record;
    type Nothing is null record;
    function Create (Ignored : not null access Nothing) return A;
    function Image (From : A) return String;
end As;

as.adb:

package body As is
    function Create (Ignored : not null access Nothing) return A is
        (null record);
    function Image (From : A) return String is ("A");
end As;

finder.ads:

with Ada.Tags;

package Finder is
    procedure Register (Name : String; Tag : Ada.Tags.Tag);
    function Find (Name : String; Default : Ada.Tags.Tag) return Ada.Tags.Tag;
end Finder;

finder.adb:

with Ada.Containers.Indefinite_Vectors;

package body Finder is
    type Name_Tag (Size : Natural) is
        record
            Name : String (1 .. Size);
            To : Ada.Tags.Tag;
        end record;

    package Name_Tag_Vectors is new Ada.Containers.Indefinite_Vectors (Positive, Name_Tag);
    Name_Tags : Name_Tag_Vectors.Vector := Name_Tag_Vectors.Empty_Vector;

    procedure Register (Name : String; Tag : Ada.Tags.Tag) is begin
        Name_Tags.Append ((Name'Length, Name, Tag));
    end Register;

    function Find (Name : String; Default : Ada.Tags.Tag) return Ada.Tags.Tag is begin
        for Tag of Name_Tags loop
            if Tag.Name = Name then
                return Tag.To;
            end if;
        end loop;

        return Default;
    end Find;
end Finder;

bs.ads:

with As;
package Bs is
    type B is new As.A with null record;
    function Create (Ignored : not null access As.Nothing) return B;
    function Image (From : B) return String;
end Bs;

bs.adb:

with Finder;
package body Bs is
    function Create (Ignored : not null access As.Nothing) return B is
        (As.Create (Ignored) with null record);
    function Image (From : B) return String is ("B");
begin
    Finder.Register ("B", B'Tag);
end Bs;

test.adb:

with As; use As;
-- with Bs; -- (uncommenting this line solves my problem, but what if I had the rest of the alphabet?)
with Finder;
with Ada.Tags.Generic_Dispatching_Constructor;
with Ada.Text_IO;

procedure Test is
    function Constructor is new Ada.Tags.Generic_Dispatching_Constructor (
        T => A,
        Parameters => Nothing,
        Constructor => Create);

    Nada : aliased Nothing := (null record);
    What : A'Class := Constructor (Finder.Find ("B", A'Tag), Nada'Access);
begin
    Ada.Text_IO.Put_Line (What.Image);
end Test;

Ответы [ 3 ]

0 голосов
/ 21 февраля 2019

Что я сделал (например, здесь ff), так это на самом деле ссылки на единицы измерения в основной программе (с pragma Unreferenced для предотвращения предупреждений).

В качестве альтернативы, вы могли бы иметьпакет, например Required_Units со всеми необходимыми with включенными, а затем with из основной программы.

Даже если бы был какой-то альтернативный процесс, вам нужно было бы указать ему, какие единицывам нужно включить;с таким же успехом можно плыть по течению и делать это в Аде!

0 голосов
/ 22 февраля 2019

Поскольку пакет Bs невидим для вашей программы, тип B - также. B. 1001 *

Итак, следующий вопрос: зачем вам регистрировать тип B, если он нигде не используется?

Если бы компилятор Ada разработал все модули (пакеты или автономные подпрограммы), которые не имеют отношения к основной программе, но видимы через путь к исходному тексту, это стало бы действительно грязным! ...

0 голосов
/ 21 февраля 2019

Компилятор считает, что на ваш пакет Bs нет ссылки, потому что на него нет.У вас нет предложения with, поэтому оно не является частью вашей программы.

Простой пример:

a.ads

package A is
    procedure Blah;
end A;

a.adb

with Ada.Text_IO;
package body A is
    procedure Blah is begin null; end Blah;
begin
    Ada.Text_IO.Put_Line("Elaborate A");
end A;

b.ads

package B is
    procedure Blah;
end B;

b.adb

with Ada.Text_IO;
package body B is
    procedure Blah is begin null; end Blah;
begin
    Ada.Text_IO.Put_Line("Elaborate B");
end B;

main.adb

with Ada.Text_IO;
with A;
procedure Main is
begin
    Ada.Text_IO.Put_Line("Main");
end Main;

Когда я запускаюmain, он печатает

Elaborate A
Main

Он не печатает Elaborate B, потому что этот пакет не является частью программы;это просто пара исходных файлов в одном каталоге.

Очевидное решение - добавить предложения with.

Я не знаю, есть ли менее очевидное решение.Если есть, это, вероятно, зависит от компилятора.Но я не уверен, почему в компиляторе есть функция, позволяющая вам встраивать неиспользуемый пакет в программу.

...