在Ada中从System.Address转换为Integer

时间:2016-05-31 18:02:32

标签: memory-management ada memory-address

在下面的示例中,我想知道为什么line 17不起作用,但是line 18?我是否可以不将System.Address直接转换为Integer(请参阅line 17)?

main.adb

with Ada.Text_IO;
with Ada.Unchecked_Conversion;
with System.Storage_Elements;

procedure Main is
   package SSE renames System.Storage_Elements;

   type Integer_Access is access Integer;
   I1_Access : Integer_Access := new Integer'(42);
   I1_Address : System.Address := I1_Access.all'Address;

   function Convert1 is new Ada.Unchecked_Conversion (System.Address, Integer);
   function Convert2 is new Ada.Unchecked_Conversion (System.Address, Integer_Access);
begin
   Ada.Text_IO.Put_Line (SSE.To_Integer (I1_Access'Address)'Img);
   Ada.Text_IO.Put_Line (SSE.To_Integer (I1_Access.all'Address)'Img);
   Ada.Text_IO.Put_Line (I1_Access.all'Img);
   Ada.Text_IO.Put_Line (Convert1 (I1_Address)'Img);  --  why does this NOT work?
   Ada.Text_IO.Put_Line (Convert2 (I1_Address).all'Img);  --  why does this work?
end Main;

结果

 140734773254664
 140243203260416
 42
-363855872
 42

3 个答案:

答案 0 :(得分:6)

如果我使用display: inline-block(大多数警告)和-gnatl(生成列表)在Mac上编译代码,我会(摘录)

-gnatwa

因为12. function Convert1 is new Ada.Unchecked_Conversion (System.Address, Integer); | >>> warning: types for unchecked conversion have different sizes 是32位而Integer(并且大多数访问类型)是64位。你的机器显然是相似的。

所以你得到一个奇怪的第五输出线(顺便说一下,我得到-490720512)的原因是它只是查看实际地址的底部32位。

您可以查看System.AddressARM 13.7.2)以获得支持的方式。

答案 1 :(得分:3)

确实有效。显然,它做的不是你期望的事情。

您可以使用System.AddressInteger转换为Unchecked_Conversion,但结果并不一定有意义。您将获得一个整数,表示System.Address值中保存的(可能是虚拟的)地址 - 它指向的任何对象的值。如果System.AddressInteger的大小不同,那么结果的意义就会更小。

Ada.Text_IO.Put_Line (Convert1 (I1_Address)'Img);

这将打印内存地址的Integer表示。它没有特别的意义。 (通常,您希望以十六进制格式查看此类地址。)

Ada.Text_IO.Put_Line (Convert2 (I1_Address).all'Img);

这将在Integer的值指示的内存位置打印对象的42I1_Address。它只是一种迂回的打印方式I1_Access.all

答案 2 :(得分:3)

如果您只想打印图像的值(如示例所示),请考虑使用函数System.Address_Image。这对指针算法不利,但会导致更好的输出(例如十六进制)