我如何处理 Ada 中动态谓词中的未初始化数据?

How do I handle uninitialized data in a dynamic predicate in Ada?

这是一些我没有按原样测试过的简化代码(因此它可能包含错误),它演示了我遇到的问题:

type Space is private;

--Depending on members of Space, determines whether Outer fully contains Inner
function Contains(Outer : Space; Inner : Space);

--Outer should fully contain Inner
type Nested_Space is
record
    Inner : Space;
    Outer : Space;
end record
with Dynamic_Predicate => Contains(Outer, Inner);

我一直无法找到一种方便的方法来初始化 Nested_Space 而不会使谓词定义的断言失败。如果我尝试先设置 Inner 的成员,Outer 的成员仍然在默认的位置。但是,如果我尝试先将成员设置为 Outer,则 Inner 的成员仍然在它们默认的位置。即使我尝试在任何一种类型上强制使用默认值,仍然无法选择肯定会在任意 Nested_Space.

范围内的默认值

甚至尝试用

之类的东西进行初始化
declare
    My_Inner : Space := (...);
    My_Outer : Space := (...);
    My_NS : Nested_Space := (Inner => My_Inner, Outer => My_Outer);
begin
    ....
end;

我似乎无法阻止它使断言失败。我可以想出一些非常笨拙的想法(例如向 Nested_Space 添加一个 Initialized : Boolean 专门用于检查谓词,或者设置两个不同空间的成员)但我希望可能有一个解决方案不会影响用例不需要的内容的记录结构。

如果 ARM 中没有解决方案,欢迎提供 GNAT 解决方案。

提前致谢!

I haven't been able to find a convenient way to initialize a Nested_Space without failing the assert defined by the predicate. If I try to set the members of Inner first, the members of Outer are still wherever they defaulted. But if I try to set the members out Outer first, the members of Inner are still wherever they defaulted.

ARM 3.2.4 (35/3) 表示,“A Static_Predicate,就像约束一样,对于子类型的所有对象始终保持为 True,除非是未初始化的变量和其他无效值。A Dynamic_Predicate,另一方面,按照上面指定的方式进行检查,但在其他时候可能变为 False。例如,修改子组件时不检查记录子类型的谓词。”您似乎是在说没有遵循这一点,并且在分配给记录组件时会检查记录谓词。如果是这样,那么您发现了编译器错误。聚合失败似乎支持这个想法。

但是,除非您 post 一个可证明您的问题的可编译示例,否则我们无法确定这是一个编译器错误。