Разработка Ады вообще не происходит

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

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

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

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

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

как.объявления:

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;

как.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;

поиск.объявления:

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.объявления:

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;

бс.адб:

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;

тест.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;

выглядит как автоматическая регистрация объектов. Не уверен, что это можно сделать на Аде (легко на С++ с static трюками)

Jean-François Fabre 20.02.2019 23:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
190
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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

а.объявления

package A is
    procedure Blah;
end 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;

б.объявления

package B is
    procedure Blah;
end B;

б.адб

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.

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

другого решения нет. Создание библиотеки не помогает. Создание инкапсулированной библиотеки также не работает, потому что вы должны указать bs в интерфейсах, чтобы она была разработана.

Jean-François Fabre 21.02.2019 20:55
Ответ принят как подходящий

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

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

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

Я собираюсь пойти с этим решением. Добавлю в процесс сборки скрипт, который ищет нужные юниты и генерирует такой пакет.

LambdaBeta 21.02.2019 17:15

Интересно, поможет ли создание проекта библиотеки и объявление всего необходимого пакета в качестве интерфейса, а затем использовать проект библиотеки в реальном исполняемом файле? наличие их в интерфейсе заставит символы существовать?

LoneWanderer 10.03.2019 20:14

@LoneWanderer, ну, я думаю, это будет зависеть от типа проекта. Если бы это были просто статические помехи, вероятно, нет; если отдельно, то возможно.

Simon Wright 10.03.2019 20:20

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

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

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

Другие вопросы по теме