I'm a C programmer trying to implement a data structure that I have implemented previously in C, but in Ada. After banging my head into the wall a few times, I've decided to come ask the stack gods for assistance.
procedure Ok is
type Node;
type Node is record
Next : access Node;
Prev : access Node;
end record;
begin
declare
a : aliased Node;
begin
a.Prev := a'Access;
end;
end;
Compilation fails because due to:
ok.adb:14:19: non-local pointer cannot point to local object which doesn't make sense to me. Which pointer is non-local? (it works if a is defined in procedure scope).
Then
procedure Ok is
type Node;
type Node is record
Next : access Node;
Prev : access Node;
end record;
procedure func(NodeOne : aliased in out Node) is
NodeP : access Node := NodeOne'Access;
begin
NodeOne.Next := NodeP;
NodeOne.Prev := NodeP;
end func;
begin
declare
a : aliased Node;
begin
func(a);
end;
end;
This one gets a runtime accessibility check failure on the
NodeOne.Next := NodeP; line
Why is the accessibility not correct?
Access types are never needed* in Ada. Those coming from languages like C, in which nothing useful can be done without pointers everywhere, have to learn a different way to think about creating software. The difference in mind set is as great as between C and a functional language.
I would advise that you learn Ada as if it had no access types until you are comfortable with the language. Then you should learn about access types so that you can understand code that uses them (usually unnecessarily).
If you are going to use access types, you should never use anonymous access types. The ARG, who wrote it, refer to the part of the ARM that defines the rules for anonymous access types as "The Heart of Darkness", and they admit that no one actually understands those rules. This means that using anonymous access types results in unpleasant surprises, and is not portable.
*True to a first-order approximation; for the kinds of S/W I deal with, true to the second and probably third order.
When using 'access in a parameter the parameter type must be "access all". Try the following:
procedure Main is
type node;
type node_access is access all node;
type Node is record
Next : node_access;
Prev : node_access;
end record;
procedure func (node_one : in out node; node_two : node_access) is
begin
Node_One.Next := Node_two;
end func;
A : aliased Node;
B : aliased Node;
begin
func(A, B'access);
end Main;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With