Ada 何时使用Pragma Pure/Preelaborate

Ada 何时使用Pragma Pure/Preelaborate,ada,pragma,elaboration,Ada,Pragma,Elaboration,是否有一套通用规则/指导原则可以帮助您理解何时更喜欢纯布拉格语、布拉格语或其他完全不同的语言?本文中给出的规则和定义有点繁重,如果能阅读一些更清晰、更适合一般情况的内容,我将不胜感激 如果我想彻底而不完全理解它的“原因”,我可以简单地尝试: 用pragma Pure标记包装规格 如果无法编译,请尝试使用pragma preeloarate 如果失败,那么我已经做了一些棘手的事情,或者需要在的基础上用-by-重新设计单元,或者重新考虑包的布局 虽然这可能会起作用(是吗?),因为建议尽可能将包装

是否有一套通用规则/指导原则可以帮助您理解何时更喜欢
纯布拉格语
布拉格语或其他完全不同的语言?本文中给出的规则和定义有点繁重,如果能阅读一些更清晰、更适合一般情况的内容,我将不胜感激

如果我想彻底而不完全理解它的“原因”,我可以简单地尝试:

  • pragma Pure标记包装规格
  • 如果无法编译,请尝试使用pragma preeloarate
  • 如果失败,那么我已经做了一些棘手的事情,或者需要在
    的基础上用
    -by-
    重新设计
    单元,或者重新考虑包的布局
虽然这可能会起作用(是吗?),因为建议尽可能将包装标记为纯包装(与PreLaborate类似),但它似乎有点脑损伤,我更愿意更好地理解这个过程。

是一个有用的指南。理想情况下,标准规则将满足大多数程序。pragmas告诉编译器替换您的精化顺序。它们应该应用于解决具体问题,而不是经验性地使用

附录:@ajb强调了布拉格语之间的一个重要区别。专家组同意问题(项目一和项目二)中概述的方法:“因此,一个好的规则是,如果可能,将单位标记为
预试验
,如果不可能,则将其标记为
详细说明
。”接着讨论情况(项目三)“这三个pragma都不能使用。”

pragma Pure
您应该在没有内部状态的任何包上使用它。它告诉包的用户,调用任何子程序都不会有副作用,因为它们不能更改任何内部状态。因此,在纯包内的库级别声明的函数在使用相同参数调用时将始终返回相同的结果特尔斯

Ada实现允许缓存纯软件包函数的返回值,如果由于这些要求而无法使用子例程的返回值,则可以省略对子例程的调用。但是,您可以通过在纯软件包内调用导入的子例程(例如,从C库)来违反约束(这些可能会改变Ada编译器不知道的某些内部状态)。如果你是邪恶的,你甚至可以使用
pragma import
从软件的其他部分导入Ada子例程,以绕过
pragma Pure
的要求。不用说:如果你在做类似的事情,不要使用
pragma Pure

编辑:为了澄清可能省略呼叫的情况,让我引用以下内容:

如果库单元被声明为纯,则如果调用后不需要结果,则允许实现忽略对库单元的库级子程序的调用。类似地,它可以忽略此类调用,只需重用先前对同一子程序的调用生成的结果,前提是任何参数都不是纯函数受限类型,所有按引用的实际参数的地址和值,以及所有按复制的实际参数的值,与之前调用时的值相同。即使子程序在调用时产生其他副作用,此权限也适用

例如,GNAT还定义,任何采用
System.Address
类型的参数或从中派生的类型的子例程,即使它们是在纯包中定义的,也不被认为是纯的,因为地址指向的位置可能会改变,但GNAT不知道地址指向什么样的结构,并且erefore无法运行任何有关参数引用值是否已更改的检查

pragma-preelorate
这告诉编译器在精化时(即在主过程开始执行之前),包不会执行任何代码。精化时,将执行以下构造:

  • 库级变量的初始化(可以是函数调用)
  • 初始化在库级别声明的任务(它们可能在主过程开始执行之前开始执行)
  • 库级
    begin…end
    块中的语句
如果您不需要这些东西,通常应该避免使用它们。尽可能使用
pragma preeloarate
,它告诉调用者可以安全地使用包,而无需在精化时执行任何操作


如果在您认为应该编译的时候没有使用其中一个pragma进行编译,请查看它为什么不编译。这可能会帮助您发现包实现或结构的问题。不要在不编译时删除pragma。因为约束会影响依赖于您的包的任何可能约束,您应该方法选择最严格的适用pragma。

我认为您考虑的是精心设计、精心设计和精心设计的主体pragma,其目的是控制精心设计的顺序。这就是它们所做的一切(只是精心设计的主体告诉编译器包需要主体).Pure和Prelaborate做了一些明确的陈述,说明一个包不包含某些类型的构造。@trashgod我不得不避免将我的问题措辞为“你能详细说明Prelaborate吗?”?"关于子程序不产生副作用的要求,
的行为是否纯粹
,它是否只适用于
函数
,或者它是否也影响
过程
?副作用方面,我们谈论的是包的本地?例如,采用
非空访问根\u流类型的流过程'Class
;流肯定是由proc更改的,那么这是否意味着包不是纯的,即使