Ada 指定另一个包中的子程序未阻塞?
SPARK限制从受保护对象中调用可能阻塞的子程序 但是,我注意到,如果调用受保护对象所在包之外的任何子程序,我会收到关于可能阻塞子程序的警告 我想用外部包告诉它调用将是非阻塞的,它缺少了什么?我试着在另一个包中放一个“addone-to-argument”子程序,但它不起作用。如果我将其移动到包含受保护对象的包中,它会这样做Ada 指定另一个包中的子程序未阻塞?,ada,spark-ada,Ada,Spark Ada,SPARK限制从受保护对象中调用可能阻塞的子程序 但是,我注意到,如果调用受保护对象所在包之外的任何子程序,我会收到关于可能阻塞子程序的警告 我想用外部包告诉它调用将是非阻塞的,它缺少了什么?我试着在另一个包中放一个“addone-to-argument”子程序,但它不起作用。如果我将其移动到包含受保护对象的包中,它会这样做 我缺少什么?在ADA2020中,有一个属性Non_Blocking,它明确标记了用于静态分析的Blocking/nonblocking属性,并且编译器确保事情是正确的 但是
我缺少什么?在ADA2020中,有一个属性
Non_Blocking
,它明确标记了用于静态分析的Blocking/nonblocking属性,并且编译器确保事情是正确的
但是,如果你被困在Ada 2012中,这并没有帮助-有一些特定的东西是“潜在阻塞”的,比如进入调用和[IIRC]事物,比如Ada.Text\u IO.Put
-SPARK的推理是,如果它是潜在阻塞的,那么你不能确保它不是非阻塞的
根据,以下是您必须注意的事项:
在受保护的操作期间,调用
可能被阻塞的操作。以下定义用于
可能会阻止操作:
- select_语句李>
- 接受声明李>
- 输入调用语句李>
- 延迟声明李>
- 中止声明李>
- 任务创建或激活李>
- 对与受保护动作具有相同目标对象的受保护子程序(或外部请求)的外部调用李>
- 对其主体包含潜在阻塞操作的子程序的调用
因此,如果您试图调用的子程序有
选择
,接受
,延迟
,或任务
,则可能会被阻塞。感谢@shark8提供详细的答案
我检查了我试图调用的方法的主体,因为它是一个简单的返回语句,所以没有手册中提到的任何效果
然而,我确实发现在我试图使用的包中打开SPARK\u Mode=>on
可以解决这个问题
这里有一个MwE重现了这个问题:
-- main.adb
pragma Profile (GNAT_Extended_Ravenscar);
pragma Partition_Elaboration_Policy (Sequential);
with P1;
procedure Main is
begin
-- Insert code here.
null;
end Main;
-- simple.ads
package Simple is
procedure Do_Nothing;
end Simple;
-- simple.adb
package body Simple is
procedure Do_Nothing is
begin
null;
end Do_Nothing;
end Simple;
-- p1.ads
pragma Profile (GNAT_Extended_Ravenscar);
pragma Partition_Elaboration_Policy (Sequential);
package P1 with
SPARK_Mode => On
is
protected Protected_Object with
SPARK_Mode => On
is
procedure Do_Something;
end Protected_Object;
end P1;
-- p1.adb
with Simple;
package body P1 with
SPARK_Mode => On
is
protected body Protected_Object
with
SPARK_Mode => On
is
procedure Do_Something is
begin
Simple.Do_Nothing;
end Do_Something;
end Protected_Object;
end P1;
@DeeDee--在下面发布一个MwE…我想问题是,除非你让SPARK看到被调用子程序的内部,否则它无法判断它是否阻塞