在比较Ada Scalar类型和子类型时,我是否需要进行范围检查?

时间:2017-04-19 20:58:13

标签: exception types ada

当比较Ada Scalar类型和受约束的子类型时,我是否需要进行范围检查?

我知道在基类型的约束子类型的赋值中,如果我不确保该值在赋值之前的范围内,那么我在运行时会遇到Range_Check异常的风险。

但是在进行比较时是否也是如此?我认为,由于用户想要的唯一知识是布尔结果,因此不需要隐式转换为基本类型或范围检查。

请注意:我正在寻找引用Ada95 LRM的答案。

实施例

declare
  type Day_Type is (SUN, MON, TUE, WED, THU, FRI, SAT);
  subtype Workday_Type is MON .. FRI; 

  Payday : constant Workday_Type := FRI;

    ...

  function Is_Payday (Day : Day_Type) 
      return Boolean is
  begin  
      return (Day = Payday);
  end Is_Payday;

begin

    -- Will this raise a RANGE_CHECK error in Is_Payday()?
    if Is_Payday(Day => SAT) then 
       ...
    elsif Is_Payday(Day => FRI) then
       ...       
    end if;

end;

到目前为止我发现了......

我还没有找到完整的答案。但我确实找到了几个有趣的数据。

离散类型的操作 / Chapter 3.5.5 para 12它说:

  

(31)对于离散型的子类型,由...提供的结果   属性Val可能不属于子类型;同样,实际   属性Pos的参数不必属于子类型。该   以下关系满足(在没有例外的情况下)   这些属性:

S'Val(S'Pos(X)) = X
S'Pos(S'Val(N)) = N
  

(20)除了显式的type_conversions之外,在类型解析规则允许的情况下,类型转换是在构造的预期类型和实际类型不同的情况下隐式执行的(见8.6)。 例如,整数文字的类型为universal_integer,并在分配给某个特定整数类型的目标时进行隐式转换。类似地,当相应的形式参数是类范围类型时,隐式转换特定标记类型的实际参数。

     

即使预期和实际类型相同,也会执行隐式子类型转换以调整操作数的数组边界(如果有)以匹配所需的目标子类型,或者如果(可能已调整)值,则执行Constraint_Error不满足目标子类型的约束。

这似乎表明隐式类型转换将始终执行到子类型(我很难阅读该语言)。但我没有看到任何声明在子类型和基本类型之间进行比较的地方。

我也对声明感到困惑:

  执行

隐式子类型转换以调整操作数的数组边界(如果有)以匹配所需的目标子类型

  1. 阵列边界参考数组类型?或者是否引用了受约束子类型的范围?
  2. 如果没有子类型,是否有目标子类型
  3. Ada 95理由......

    我可能在搜索中错过了答案。但我正在寻找这种或那种方式的明确证据。

    很抱歉阅读不久。

2 个答案:

答案 0 :(得分:7)

您可能会发现带注释的ARM版本(AARM95 3.2)很有帮助(请注意,您的引用是针对未维护的AdaHome网站;更喜欢http://www.adaic.org)。

子类型具有类型和可能的约束:

type T is ...;
subtype S1 is T;            -- effectively a renaming of T
subtype S2 is T range ...;  -- (added) constraints

并且子类型的操作是其类型的操作,这就是为什么你可以在没有转换的情况下编写比较Day = Payday的原因。我们知道Workday_TypeDay_Type,因此我们可以直接进行比较。

Workday_Type (Day) = Payday确实存在CE风险,但您或编译器无需这样做。

答案 1 :(得分:1)

就像Simon Wright has explained一样,操作是类型的操作,而子类型形成类型值的子集,而不是具有不同操作的不同类型。

为了便于说明,请考虑"+"

type N is range 0 .. 10;

X : constant N := N'Base'(-1) + N'(2);

许多Ada规则适用,而IANALL,我记得LLawyers强调规则的制定是为了在不引起异常的情况下产生数学上(逻辑上)正确的结果,即使看起来某些操作涉及超出范围的值一路上。 LRM 4.5中有一个提示。所以,我希望relational_operator规则,特别是"=",也是支持性的。