Rationale for Ada 2005
9.4 Postscript
Nothing is ever perfect and a number of small imperfections
have been found in Ada 2005 since the Amendment was completed. We will
briefly look at the more obvious of these.
Perhaps the most noticeable
since it affects the syntax is described by two Ada Issues namely
AI05-15
and
AI05-53.
The former points out that in an extended return statement
it is useful to be able to mark a return object as
constant whereas
the latter concludes that it is unwise to be able to mark the object
as
aliased. So the syntax which reads
return defining_identifer: [aliased] return_subtype_indication [:= expression} {do
should read
return defining_identifer: [constant] return_subtype_indication [:= expression} {do
Aliased is unwise on the return object (the
object in the extended return statement) because the result object (remember
that the result of a function is itself an object and might indeed be
providing the initial value of a limited object) need not be aliased
and this can lead to some curious anomalies.
** Formatting stopped here **
Another issue concerning
the extended return statement is
AI05-32
regarding class wide functions. In Section
4.5
we saw that a function could return an indefinite type but nevertheless
the return object could be declared to be constrained thus
function Make( ... ) return UA is
begin
...
return R: UA(1 .. N) do
...
end return;
end Make;
The same rule should
apply to class wide types. Thus if the return type is class wide such
as Device'Class then we should be allowed to write
function Make( ... ) return Device'Class is
begin
...
return R: My_Device do
...
end return;
end Make;
where My_Device is covered by Device'Class. This
is now permitted by
AI05-32.
Another issue regarding functions is that a function
that returns an abstract type must be abstract (this was true in Ada
95 of course). However,
AI05-73
points out that a function that returns an access to an abstract type
must also be abstract in order to avoid dispatching problems.
A trivial point is that a child package may not have
a limited with clause
for its parent (
AI05-40).
Limited with clauses are forbidden in a number of situations in order
to avoid confusion. One such rule is that a package cannot have both
a with clause and a limited with clause for the same unit. In the case
of a child it effectively has an implicit with clause for its parent
so disallowing a limited with clause is really the same rule.
A further trivial point mentioned by
AI05-16
is that
(others => <>) is
permitted as an aggregate for a null record.
There are a number of corrections and clarifications
regarding categorization. One is that a limited view is always considered
pure (
AI05-34).
Another is that Preelaborable_Initialization
should not be restricted to just private types (
AI05-28).
Two pragmas have been added by
AI05-9.
These are Independent and Independent_Components (much like Atomic and
Atomic_Components).
They stipulate that the objects concerned are independently addressable
and so can be manipulated independently without explicit synchronization
in a multitasking program. This arose from consideration of confirming
representation clauses.
There are a number
of issues concerning null exclusions. One is that null exclusions must
textually match for full conformance. Thus we cannot write
package P is
type T is tagged null record;
procedure Q(X: access T);
end P;
package body P is
procedure Q(X: not null access T); -- illegal, doesn't match
end P;
The standard as written doesn't cover this case since
it can be argued that in the specification
Q
excludes null since it is controlling whereas in the body it excludes
null because it says so. But
AI05-45
concludes that the intent was to require lexical matching to avoid confusion.
Another issue concerning null exclusions is addressed
by
AI05-62.
If a deferred constant has a null exclusion then the full declaration
must also have a null exclusion. But the reverse is not true. If a deferred
constant does not have a null exclusion then the full declaration might
still have a null exclusion. This follows the same pattern as for constraints.
If a deferred constant has a constraint then the full declaration must
have a matching constraint but the reverse is not true.
It will recalled that
the issue of null exclusions causes a potential inconsistency between
Ada 95 and Ada 2005.
See
9.1.2,
item 4 and Section
3.2. It was therefore proposed
that Ada 95 should permit
not null in the specification of an
access parameter thus
procedure P(X: not null access T);
The idea was that for Ada 95 this was merely a comment
but on transition to Ada 2005 it would give identical behaviour in all
cases so that the inconsistency would be avoided. This was written up
as
AI95-447
and approved by the ARG. However, when it came to ratification by WG9
a difficulty arose. From the point of view of ISO there is only ever
one Ada standard and the current incarnation is what we call Ada 2005.
Thus WG9 can no longer talk about Ada 95. Nevertheless compiler writers
are encouraged to permit this "comment" in Ada 95 code (and
a test has been added to the test suite).
There are a number of other AIs regarding Ada 2005
which cover matters such as corner cases in accessibility rules. These
are too obscure to discuss here and are unlikely to impact on the typical
programmer.
However, it is hard to avoid the temptation to mention
just one more AI with which to finish this brief survey. This concerns
an error in the description of the procedure Set_Line. The idea of Set_Line
is to move down the page and of course if the required line number is
the current line number then do nothing. But if the current position
is beyond the required position first do New_Page and then move down
the page the required number of lines. Unfortunately, if the new position
required is at the beginning of the page (that is the parameter of Set_Line
is one) and New_Page is called then, according to the wording, this results
in New_Line(0) being called and this does not do nothing as hoped but
raises Constraint_Error because the parameter of New_Line is of the subtype
Positive_Count which excludes zero! This error has been there since Ada
83. Clearly all implementers have been doing the correct thing and just
ignored the foolish wording. This is now corrected by
AI05-38.
© 2005, 2006, 2007 John Barnes Informatics.
Sponsored in part by: