使用 interface.c.pointer 将访问类型的地址递增为 c 中的指针?
Increment address of access type as pointer in c using interface.c.pointer?
注意到一些意外行为:Put_Line(Integer'Image(Var.all)); var:=var+5;
——它给出 1
,var+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;
你的 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
您已告诉编译器将 space 保留 5 int
秒(20 字节),您已在其中放置了一些数据。编译器可以随心所欲地使用数组末尾之外的 space ;它肯定不属于你,你不知道它的用途:HANDS OFF!
因此,当您将指针递增到数组的第十个元素(如果您声明它至少有 10 个元素长)时,您正在寻址未定义的数据。您没有理由认为它是 int
;它可能是字符串的一部分,可能是 double
的中间,也可能是任何东西。在台式机上,不太可能是内存位置,读取时会导致机器着火;在微控制器中不太可能运行你的烤面包机。
通过指针写入几乎肯定会使您的程序立即崩溃,或者在执行数千条指令后,您将很难找到错误。
程序的这种行为在 Ada 词中是“错误的”;我认为 C 词是“未定义”的。
注意到一些意外行为:Put_Line(Integer'Image(Var.all)); var:=var+5;
——它给出 1
,var+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;
你的 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
您已告诉编译器将 space 保留 5 int
秒(20 字节),您已在其中放置了一些数据。编译器可以随心所欲地使用数组末尾之外的 space ;它肯定不属于你,你不知道它的用途:HANDS OFF!
因此,当您将指针递增到数组的第十个元素(如果您声明它至少有 10 个元素长)时,您正在寻址未定义的数据。您没有理由认为它是 int
;它可能是字符串的一部分,可能是 double
的中间,也可能是任何东西。在台式机上,不太可能是内存位置,读取时会导致机器着火;在微控制器中不太可能运行你的烤面包机。
通过指针写入几乎肯定会使您的程序立即崩溃,或者在执行数千条指令后,您将很难找到错误。
程序的这种行为在 Ada 词中是“错误的”;我认为 C 词是“未定义”的。