Reputation: 2678
I have an Ada task, Do_Something
, that needs to "invoke" itself. The way I think of it coming from C++, I have a thread running void Do_Something()
and sometimes void Do_Something()
needs to spawn more threads that also run void Do_Something()
.
Ada (which I'm learning) doesn't like that. This seems to be a M(non)WE:
task body A_Task is
new_task: access A_Task;
my_level: Natural;
begin
accept Do_Something(level: in Natural) do
my_level := level + 1;
end Do_Something;
if my_level < 4 then
new_task := new A_Task;
new_task.Do_Something(my_level);
end if;
end A_Task;
GNAT at least doesn't like this, reporting an error at new_task.Do_Something(my_level);
because
task type cannot be used as type mark within its own spec or body
Yet this is easily circumvented by adding a procedure like this outside the task:
procedure Circumvent(level: Natural) is
new_task: access A_Task;
begin
new_task := new A_Task;
new_task.Do_Something(level + 1);
end Circumvent;
then modifying the if
statement in A_Task
's body to this:
if my_level < 4 then
Circumvent(my_level);
end if;
This latter version passes GNAT (now we have a M***W***E) and the program runs just fine, even in a non-trivial example I was playing with last night.
This workaround seems so straightforward that I don't understand why the compiler should raise the first error at all! I imagine I must be attacking this problem in completely the wrong way. Is this considered good Ada technique, and if not, what would be the Ada-like way to do this sort of thing?
Upvotes: 1
Views: 270
Reputation: 6430
This behaviour is specified in RM 8.6(17/3): "If a usage name appears within the declarative region of a type_declaration and denotes that same type_declaration, then it denotes the current instance of the type (rather than the type itself);"
This implies that the actual name of the type cannot be used to instantiate a different object.
A wrapper (like yours) would then be one way of doing it.
A subtype should also work subtype Foo is A_Task;
Be aware, though, that the C++ way of thinking/doing things is rarely the Ada way of doing things
Upvotes: 5