确实,从类型的子类型P中分配U不需要检查,因为不存在不匹配(即使子类型与类型具有相同的范围; subtype P is U;完全合法且可能有用!)
另一种方式,从类型到子类型,将涉及检查,至少如果子类型是子范围.
从外部来看,具有不同范围的另一种类型也是如此.但是,有一个微妙的区别; 使用类型/子类型,您可以在不进行转换的情况下将一个分配给另一个,如果没有检查,但是在类型/类型中,您必须在分配之前进行类型转换,并且将在转换时检查任何约束违规,而不是分配.
这可能有助于说明这一点:
procedure Drimades is
type Upper is range 10 .. 20;
subtype Part is Upper range 10 .. 15;
type Lower is new Upper range 10 .. 15;
procedure Assign_U_To_P (U : Upper; To : out Part) is
begin
To := U; -- requires check
end Assign_U_To_P;
procedure Assign_P_To_U (P : Part; To : out Upper) is
begin
To := P; -- no check needed
end Assign_P_To_U;
procedure Assign_U_To_L (U : Upper; To : out Lower) is
begin
To := Lower (U); -- requires check
end Assign_U_To_L;
procedure Assign_L_To_U (L : Lower; To : out Upper) is
begin
To := Upper (L); -- no check required
end Assign_L_To_U;
U : Upper;
P : Part;
L : Lower;
begin
Assign_U_To_P (20, P);
Assign_P_To_U (15, U);
Assign_U_To_L (20, L);
Assign_L_To_U (15, U);
end Drimades;
Run Code Online (Sandbox Code Playgroud)
用GNAT编译这个并且开关-gnatG产生这个中间表示,不太难以解释我希望:
procedure drimades is
type drimades__upper is range 10 .. 20;
[type drimades__TupperB is new short_short_integer]
freeze drimades__TupperB []
subtype drimades__part is drimades__upper range 10 .. 15;
[type drimades__TlowerB is new drimades__TupperB]
freeze drimades__TlowerB []
type drimades__lower is new drimades__upper range 10 .. 15;
procedure drimades__assign_u_to_p (u : drimades__upper; to : out
drimades__part) is
begin
[constraint_error when
not (u in 10 .. 15)
"range check failed"]
to := u;
return;
end drimades__assign_u_to_p;
procedure drimades__assign_p_to_u (p : drimades__part; to : out
drimades__upper) is
begin
to := p;
return;
end drimades__assign_p_to_u;
procedure drimades__assign_u_to_l (u : drimades__upper; to : out
drimades__lower) is
begin
[constraint_error when
not (u in 10 .. 15)
"range check failed"]
to := drimades__lower(u);
return;
end drimades__assign_u_to_l;
procedure drimades__assign_l_to_u (l : drimades__lower; to : out
drimades__upper) is
begin
to := drimades__upper(l);
return;
end drimades__assign_l_to_u;
u : drimades__upper;
p : drimades__part;
l : drimades__lower;
begin
drimades__assign_u_to_p (20, p);
drimades__assign_p_to_u (15, u);
drimades__assign_u_to_l (20, l);
drimades__assign_l_to_u (15, u);
return;
end drimades;
Run Code Online (Sandbox Code Playgroud)