将 Ada 标量类型与子类型进行比较时,我需要进行范围检查吗?
When comparing Ada Scalar type With a subtype do I need to range check?
将 Ada 标量类型与受约束的子类型进行比较时,我需要进行范围检查吗?
我知道在从基本类型到受约束子类型的赋值中,如果我在赋值之前不能确保该值在范围内,我将面临运行时出现 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 它说:
3.2 Types and Subtypes -- 本章只讨论类型和子类型是如何定义的。
3.5.5 Operations of Discrete Types -- 本章中有有趣的注释,但我不确定它或本章中的其他内容是否相关。
(31) For a subtype of a discrete type, the result delivered by the
attribute Val might not belong to the subtype; similarly, the actual
parameter of the attribute Pos need not belong to the subtype. The
following relations are satisfied (in the absence of an exception) by
these attributes:
S'Val(S'Pos(X)) = X
S'Pos(S'Val(N)) = N
4.5.1 Logical Operators and Short Circuit Control Forms -- 这里没有关于类型与子类型的内容。
4.6 Type Conversions -- Now, this is where I think the golden answer lies. But its not jumping out at me. I see a small clue in note (20).
(20) In addition to explicit type_conversions, type conversions are performed implicitly in situations where the expected type and the actual type of a construct differ, as is permitted by the type resolution rules (see 8.6). For example, an integer literal is of the type universal_integer, and is implicitly converted when assigned to a target of some specific integer type. Similarly, an actual parameter of a specific tagged type is implicitly converted when the corresponding formal parameter is of a class-wide type.
Even when the expected and actual types are the same, implicit subtype conversions are performed to adjust the array bounds (if any) of an operand to match the desired target subtype, or to raise Constraint_Error if the (possibly adjusted) value does not satisfy the constraints of the target subtype.
这似乎暗示隐式类型转换将始终执行到子类型(我很难阅读该语言)。但是我没有看到任何地方表明需要在子类型和基本类型之间进行比较。
我也被这个说法搞糊涂了:
implicit subtype conversions are performed to adjust the array bounds (if any) of an operand to match the desired target subtype
- 数组边界是否引用数组类型?还是它引用了受约束子类型的范围?
- 如果没有子类型,是否有目标子类型?
Ada 95 基本原理...
Ada95 Rationale - Part I Overview -- 这级别太高了。这里没有任何帮助。
Ada95 Rationale - Part II - 3.1 Types, Classes, Objects and Views -- 这部分有很多关于类型的有见地的信息,但仍然 none 与比较类型和子类型相关
我可能刚刚在搜索中错过了答案。但我正在以某种方式寻找明确的证据。
抱歉阅读时间过长。
您可能会找到带注释的 ARM 版本 (AARM95 3.2) helpful (note, your references were to the unmaintained AdaHome web site; prefer 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_Type
就是一个Day_Type
,所以直接比较就可以了
确实Workday_Type (Day) = Payday
存在CE风险,但你或编译器没有必要这样做。
就像 一样,操作是一个类型的操作,而 subtype 形成一个类型的值的子集,而不是具有不同操作的不同类型。
为了便于说明,请考虑 "+"
:
type N is range 0 .. 10;
X : constant N := N'Base'(-1) + N'(2);
许多 Ada 规则适用,虽然 IANALL,但我记得 LLawyers 强调规则的制定是为了产生数学上(逻辑上)正确的结果而不会引发异常,即使看起来某些操作涉及的值超过沿途的一个范围。 LRM 4.5 中有提示。所以,我希望 relational_operator
规则,特别是 "="
也能提供支持。
将 Ada 标量类型与受约束的子类型进行比较时,我需要进行范围检查吗?
我知道在从基本类型到受约束子类型的赋值中,如果我在赋值之前不能确保该值在范围内,我将面临运行时出现 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 它说:
3.2 Types and Subtypes -- 本章只讨论类型和子类型是如何定义的。
3.5.5 Operations of Discrete Types -- 本章中有有趣的注释,但我不确定它或本章中的其他内容是否相关。
(31) For a subtype of a discrete type, the result delivered by the attribute Val might not belong to the subtype; similarly, the actual parameter of the attribute Pos need not belong to the subtype. The following relations are satisfied (in the absence of an exception) by these attributes:
S'Val(S'Pos(X)) = X S'Pos(S'Val(N)) = N
4.5.1 Logical Operators and Short Circuit Control Forms -- 这里没有关于类型与子类型的内容。
4.6 Type Conversions -- Now, this is where I think the golden answer lies. But its not jumping out at me. I see a small clue in note (20).
(20) In addition to explicit type_conversions, type conversions are performed implicitly in situations where the expected type and the actual type of a construct differ, as is permitted by the type resolution rules (see 8.6). For example, an integer literal is of the type universal_integer, and is implicitly converted when assigned to a target of some specific integer type. Similarly, an actual parameter of a specific tagged type is implicitly converted when the corresponding formal parameter is of a class-wide type.
Even when the expected and actual types are the same, implicit subtype conversions are performed to adjust the array bounds (if any) of an operand to match the desired target subtype, or to raise Constraint_Error if the (possibly adjusted) value does not satisfy the constraints of the target subtype.
这似乎暗示隐式类型转换将始终执行到子类型(我很难阅读该语言)。但是我没有看到任何地方表明需要在子类型和基本类型之间进行比较。
我也被这个说法搞糊涂了:
implicit subtype conversions are performed to adjust the array bounds (if any) of an operand to match the desired target subtype
- 数组边界是否引用数组类型?还是它引用了受约束子类型的范围?
- 如果没有子类型,是否有目标子类型?
Ada 95 基本原理...
Ada95 Rationale - Part I Overview -- 这级别太高了。这里没有任何帮助。
Ada95 Rationale - Part II - 3.1 Types, Classes, Objects and Views -- 这部分有很多关于类型的有见地的信息,但仍然 none 与比较类型和子类型相关
我可能刚刚在搜索中错过了答案。但我正在以某种方式寻找明确的证据。
抱歉阅读时间过长。
您可能会找到带注释的 ARM 版本 (AARM95 3.2) helpful (note, your references were to the unmaintained AdaHome web site; prefer 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_Type
就是一个Day_Type
,所以直接比较就可以了
确实Workday_Type (Day) = Payday
存在CE风险,但你或编译器没有必要这样做。
就像
为了便于说明,请考虑 "+"
:
type N is range 0 .. 10;
X : constant N := N'Base'(-1) + N'(2);
许多 Ada 规则适用,虽然 IANALL,但我记得 LLawyers 强调规则的制定是为了产生数学上(逻辑上)正确的结果而不会引发异常,即使看起来某些操作涉及的值超过沿途的一个范围。 LRM 4.5 中有提示。所以,我希望 relational_operator
规则,特别是 "="
也能提供支持。