Ada:任务类型作为自己身体中的任务标记

时间:2018-05-08 13:48:07

标签: compiler-errors task ada

我有一个Ada任务,Do_Something,需要"调用"本身。我认为它来自C ++的方式,我有一个运行void Do_Something()的线程,有时候void Do_Something()需要生成更多运行void Do_Something()的线程。

Ada(我在学习)并不喜欢这样。这似乎是M(非)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至少不会这样,在new_task.Do_Something(my_level);报告错误,因为

task type cannot be used as type mark within its own spec or body

然而,在任务之外添加这样的程序很容易避免这种情况:

procedure Circumvent(level: Natural) is
    new_task: access A_Task;
begin
    new_task := new A_Task;
    new_task.Do_Something(level + 1);
end Circumvent;

然后将if正文中的A_Task声明修改为:

  if my_level < 4 then
    Circumvent(my_level);
  end if;

后一个版本通过GNAT(现在我们有一个M *** W *** E)并且该程序运行得很好,即使是在我昨晚玩的非常重要的例子中。

这种解决方法看起来非常简单,我不明白为什么编译器应该首先引发第一个错误!我想我必须以完全错误的方式攻击这个问题。这被认为是很好的Ada技术,如果没有,那么做Ada的方式会是什么样的呢?

1 个答案:

答案 0 :(得分:4)

此行为在RM 8.6(17/3)中指定: &#34;如果一个用法名出现在type_declaration的声明性区域中并且表示相同的type_declaration,那么它表示该类型的当前实例(而不是类型本身);&#34;

这意味着该类型的实际名称不能用于实例化不同的对象。 然后,包装器(就像你的包装器)就是这样做的一种方式。 子类型也应该有效subtype Foo is A_Task;

请注意,C ++的思考/做事方式很少是Ada的做事方式