Ada 没有适用于程序/功能的全球合同

Ada 没有适用于程序/功能的全球合同,ada,gnat,spark-ada,Ada,Gnat,Spark Ada,我在SPARK模块中有一个过程,它调用标准的Ada-Text\u IO.Put\u Line 在证明过程中,我收到以下警告警告:没有可用于“放线”的全局合同 我已经知道如何将各自的数据依赖关系契约添加到我自己编写的过程和函数中,但是如何将它们添加到其他人编写的无法编辑源文件的过程/函数中 我查看了Adacore SPARK 2014用户指南的第5.2节和第7.4节,但没有找到解决我问题的示例。我认为您不能在您不拥有的代码上添加SPARK契约,特别是来自Ada标准的代码 关于Text_Io,我在参

我在SPARK模块中有一个过程,它调用标准的
Ada-Text\u IO.Put\u Line

在证明过程中,我收到以下警告
警告:没有可用于“放线”的全局合同

我已经知道如何将各自的数据依赖关系契约添加到我自己编写的过程和函数中,但是如何将它们添加到其他人编写的无法编辑源文件的过程/函数中


我查看了Adacore SPARK 2014用户指南的第5.2节和第7.4节,但没有找到解决我问题的示例。

我认为您不能在您不拥有的代码上添加SPARK契约,特别是来自Ada标准的代码

关于Text_Io,我在参考手册中发现它可能对您很有价值

编辑

与Martin所说的相比,另一个解决方案是创建一个包装包

由于Spark要求您处理Spark包,但允许您依赖带有Ada主体的Spark规范,因此解决方案是构建一个包含Ada.Text_io调用的Spark包


这可能会很乏味,因为您将不得不包装可能的异常,可能定义特定的类型等等,但这样,您就可以在完整的Spark软件包中释放VCs。

这意味着分析仪无法“看到”调用此函数时全局变量是否会受到影响。因此,它假设这个调用没有修改任何内容(否则所有其他证明都可能立即被驳斥)。对于您的特定示例,这可能是一个有效的假设,但在嵌入式系统上可能无效,因为Put_行的自定义实现可能会起到任何作用

有两种方法可以传达缺失的信息:

  • 验证器可以检查函数的源代码。然后,它可以尝试自己生成全球合约
  • 明确规定了全局合同,请参见RM 6.1.4()
  • 在这种情况下,您正在调用的过程是运行时系统(RTS)的一部分,因此源不可见,您可能无法/不应该更改它

    实践中该怎么做?

    抑制警告几乎从来都不是一个好主意,尤其是当你在做一些安全关键的事情时。通常,必须更改代码,直到警告消失,或者必须开始一些调整过程

    如果您对分析结果很认真,我建议不要使用这样的子程序。如果您确实需要输出,可以编写自己的过程来替换RTS子程序,或者确保子程序确实没有副作用。Frédéric的链接进一步证实了这一点:即使被调用方没有副作用,您也不知道它是否会引发特定输入的异常(例如,非常长的字符串)


    如果你对结果不太认真,那么你可以考虑这个特定的警告作为你可以使用的警告。

    用于开发星火应用程序的包装包可以在这里找到:


    非常感谢您参考参考手册
    Put_Line
    既没有正面提到,也没有负面提到,这意味着我应该能够使用该函数。那么,我该如何告诉SPARK抑制警告?包装程序是一种可行的替代方法吗?您是否可以使用例如
    pragma警告(Off,“*Put_Line*”)?(不确定那里的通配符)@SimonWright:pragma警告(关闭…);按照您的建议工作。因为我使用Put_行仅用于调试,所以我刚刚删除了该行并对此感到满意。这非常有用。非常感谢你!