Ada: how to solve “Circular Unit Dependency”?

不打扰是莪最后的温柔 提交于 2019-12-12 13:48:38

问题


Suppose I have two records: Person and Animal. Each record is in a separate package.

Package persons:

with animals;
use animals;

package persons is 

    type person is record
     ...
     animalref: animalPOINTER;
     ...
    end record;

    type personPOINTER is access person;

end persons;

Package animals:

with persons;
use persons;

package animals is 
    type animal is record
     ...
     ownerref:  personPOINTER;
     ...
    end record;

    type animalPOINTER is access animal;

end animals;

I have Circular Unit Dependency here, and compiler produces fatal error.

Does anyone have a pattern to address such issue ?

Thanks!


回答1:


You need limited with, which was introduced to address exactly this problem. See the Rationale for Ada 2005, section 4.2.

Animals and Persons are symmetric (my editor has adjusted the layout and casing; I’ve added one record component to each so the demo program, below, can print something):

limited with Animals;
package Persons is

   --  One of the few things you can do with an incomplete type, which
   --  is what Animals.Animal is in the limited view of Animals, is to
   --  declare an access to it.
   type AnimalPOINTER is access Animals.Animal;

   type Person is record
      Name : Character;
      Animalref : AnimalPOINTER;
   end record;

end Persons;

limited with Persons;
package Animals is

   type PersonPOINTER is access Persons.Person;

   type Animal is record
      Name : Character;
      Ownerref : PersonPOINTER;
   end record;

end Animals;

The demo program has the full view of Animals and Persons. This example is pretty clumsy; you may be able to organise things better by adding subprograms to Animals and Persons. Note that the body of Animals can (and must) with Persons; if it needs to use anything in Persons.

with Ada.Text_IO; use Ada.Text_IO;
with Animals;
with Persons;
procedure Animals_And_Persons is
   A : Persons.animalPOINTER := new Animals.Animal;
   P : Animals.PersonPOINTER := new Persons.Person;
begin
   A.all := (Name => 'a', Ownerref => P);
   P.all := (Name => 'p', Animalref => A);
   Put_Line (P.Name & " owns " & P.Animalref.Name);
   Put_Line (A.Name & " is owned by " & A.Ownerref.Name);
end Animals_And_Persons;

which when compiled and run gives

$ ./animals_and_persons 
p owns a
a is owned by p


来源:https://stackoverflow.com/questions/34694211/ada-how-to-solve-circular-unit-dependency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!