Как напечатать адрес, на который указывает переменная доступа ada?

Я хочу напечатать адрес переменной доступа (указателя) для целей отладки.

type Node is private;
type Node_Ptr is access Node;

procedure foo(n: in out Node_Ptr) is
    package Address_Node is new System.Address_To_Access_Conversions(Node);
    use Address_Node;
begin
    Put_Line("node at address " & System.Address_Image(To_Address(n)));
end foo;

Address_Image возвращает строковое представление адреса.
System.Address_To_Access_Conversions — это универсальный пакет для преобразования адресов и типов доступа (см. ARM 13.7.2), определяемый следующим образом:

generic
    type Object(<>) is limited private;
package System.Address_To_Access_Conversions is
   -- [...]
   type Object_Pointer is access all Object;
   -- [...]
   function To_Address(Value : Object_Pointer) return Address;
   -- [...]
end System.Address_To_Access_Conversions;

gnat выдает следующие ошибки для процедуры foo, определенной выше:

expected type "System.Address_To_Access_Conversions.Object_Pointer" from instance at line...
found type "Node_Ptr" defined at ...

Object_Pointer определен как доступ ко всем объектам. Насколько я понимаю, тип Object — это Node, поэтому Object_Ptr — это доступ ко всем Node. На что жалуется комар?
Думаю, мое понимание дженериков Ады ошибочно, и я неправильно использую System.Address_To_Access_Conversions.

РЕДАКТИРОВАТЬ: я скомпилировал свой код с помощью «gnatmake -gnatG», чтобы увидеть общий экземпляр:

package address_node is
    subtype btree__clear__address_node__object__2 is btree__node;
    type btree__clear__address_node__object_pointer__2 is access
        all btree__clear__address_node__object__2;
    function to_address (value :
        btree__clear__address_node__object_pointer__2) return
        system__address;
end address_node;

btree__node — это искаженное имя типа Node, как определено выше, поэтому я действительно думаю, что тип параметра для to_address() правильный, но gnat жалуется (см. выше).


ada
person georg    schedule 06.05.2010    source источник


Ответы (2)


В данный момент передо мной нет компилятора, но разве это не работает?

procedure foo(n: in out Node_Ptr) is 
begin 
   Put_Line("node at address " & System.Address_Image(n.all'address)); --'
end foo; 
person T.E.D.    schedule 06.05.2010
comment
Да. Про явное разыменование переменных доступа я ничего не нашел, поэтому предположил, что в Аде такого нет. Теперь я знаю лучше, спасибо! - person georg; 07.05.2010
comment
Вы также можете сделать 'access, чтобы получить указатель, что немного полезнее. Вы действительно не должны делать ни того, ни другого в Аде, за исключением некоторых очень редких обстоятельств. Я предлагаю вам перейти к приложению K (Атрибуты, определяемые языком) вашего дружественного соседства Ada LRM и внимательно прочитать его. Там много хорошего. - person T.E.D.; 07.05.2010

Хорошо, явное преобразование типов делает свое дело:

procedure Foo(n: in out Node_Ptr) is
    package Address_Node is new System.Address_To_Access_Conversions(Node);
    use Address_Node;
    p : Address_Node.Object_Pointer;
begin
    p := Address_Node.Object_Pointer(n);
    Put_Line("node at address " & System.Address_Image(To_Address(p)));
end Foo;

Требуется некоторое время, чтобы привыкнуть к Аде... ;-)

person georg    schedule 06.05.2010