使用interface.c.pointer将访问类型的地址增加为c中的指针?

时间:2015-01-10 18:14:48

标签: pointers ada

注意到一些意外行为:Put_Line(Integer'Image(Var.all)); var:=var+5; - 它会1var+6然后2,如果var+7则会{0},var+8那么-1,有人可以解释一下吗?

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C.Pointers;
procedure Access_Pointer_Arithmetic is
   type Myarr_Indices is range 1 .. 5;
   type Myarr is array (Myarr_Indices range <>) of aliased Integer;
   Myarr_Terminator : constant Integer := 0;

   package Myarr_Pointer_Arithmetic is new Interfaces.C.Pointers
     (Myarr_Indices, Integer, Myarr, Myarr_Terminator);

   use Myarr_Pointer_Arithmetic;
   Myarr_Var : aliased Myarr := (2, 5, 7, 9, 0);
   Var : Myarr_Pointer_Arithmetic.Pointer :=Myarr_Var(Myarr_Var'First)'access;
begin
   Put_Line(Integer'Image(Var.all));
   var:=var+1;
   Put_Line(Integer'Image(Var.all));-- why 1?
   var:=var+8;
   Put_Line(Integer'Image(Var.all));-- why -1 and some time different 4-7 digits no?
end Access_Pointer_Arithmetic;

1 个答案:

答案 0 :(得分:2)

您的Ada代码与此C:

完全相同
#include <stdio.h>

int main()
{
  int arr[5] = {2, 5, 7, 9, 0};
  int *p = arr;
  printf("%d\n", *p);
  p += 1;
  printf("%d\n", *p);
  p += 8;
  printf("%d\n", *p);
  return 0;
}

当它运行时,产生(在我的机器上)

2
5
32767

您已告诉编译器为5 int s(20字节)保留空间,您已在其中放置了一些数据。无论喜欢什么,编译器都可以自由地使用数组末尾之外的空间;它当然不属于你,你不知道它用于什么:HANDS OFF!

因此,当您将指针递增到数组的第十个元素时,如果您已将其声明为至少10个元素长,则表示您正在寻址未定义的数据。你没有理由认为它是int;它可能是字符串的一部分,它可能是double的中间,它可能是任何东西。在桌面计算机上,它不太可能是一个内存位置,它会导致机器在读取时着火;在运行烤面包机的微控制器中不太可能。

通过指针写入几乎可以保证您的程序立即崩溃,或者稍后当您在查找错误时遇到麻烦时会发出数千条指令。

Ada对于这种程序行为的说法是“错误的”;我相信C字是“未定义的”。