When comparing Ada Scalar type With subtype, do I need to check the range?

When comparing an Ada Scalar type with a restricted subtype, do I need to check the range?

I know that when assigning to a constrained subtype from a base type, I run the risk of a Range_Check exception at runtime if I don't guarantee that the value is within the range before the assignment.

But is this also true when making comparisons? I think that since the only knowledge the user wants to return is a boolean result that no implicit conversion to base type or range checking is required.

Pay attention . I'm looking for an answer that links to Ada95 LRM .

Example

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;

      

What I have found so far ...

I haven't found a complete answer. But I found some interesting bits of data.

Discrete Type Operations / Chapter 3.5.5 paragraph 12 it says:

(31) For a subtype of a discrete type, the result obtained by the Val attribute may not belong to the subtype; similarly, the actual parameter of the Pos attribute must not be of a subtype. the following relationships (in the absence of an exception) hold these attributes:

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

      

(20) In addition to explicit type_type conversions, type conversions are performed implicitly in situations where the expected type and the actual type of a construct are different, as permitted by the type resolution rules (see 8.6). For example, an integer literal is of type universal_integer and is implicitly converted when the target is assigned a specific integer type. Likewise, an actual parameter of a certain labeled type is implicitly converted when the corresponding formal parameter is in a class.

Even if the expected and actual types are the same, implicit subtype conversions are performed to adjust the array bounds (if any) of the operand to match the desired target subtype, or raise Constraint_Error if the (possibly adjusted) value does not satisfy the target subtype constraints.

This seems to suggest that implicit type conversions will always be done to the subtype (the language is hard for me to read). But I don't see anywhere where a comparison is specified between subtype and base type.

I am also confused by the statement:

implicit subtype conversions are performed to adjust the bounds of the array (if any) of the operand corresponding to the target subtype

  • Does array of arrays support arrays of arrays? or is it referring to the range of a restricted subtype?
  • Is there a target subtype if there is no subtype?

Ada 95 Rationale ...


I probably just missed the answer in my search. But I'm looking for definitive proof anyway.

Sorry for the long reading.

+3


source to share


2 answers


You may find the annotated ARM version ( AARM95 3.2 ) helpful (note that your links were to the unsupported AdaHome website; prefer http://www.adaic.org ).

The subtype has a type and possibly restrictions:

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

      



and the operations of a subtype are of the type of its type, so you can write a comparison Day = Payday

without conversions. We know what a Workday_Type

is Day_Type

, so we can just do the comparison directly.

It is true that Workday_Type (Day) = Payday

runs the CE risk, but you don't need either a compiler to do this.

+7


source


Just like Simon Wright explained , operations are performed on a type, whereas a subtype forms subsets of the values ​​of a type, not a different type with different operations.

To illustrate, consider "+"

this:



type N is range 0 .. 10;

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

      

A number of Ada rules apply, and although IANALL, I remember LLawyers emphasizing that the rules are made in such a way that it is possible to obtain a mathematically (logically) correct result without invoking exceptions, even if some operation appears to involve values ​​greater than range along the way. There is a hint in LRM 4.5 . Therefore, I would expect that the rules relational_operator

, "="

in particular, will also be supported.

+1


source







All Articles