Rationale for Ada 2005

John Barnes
Contents   Index   References   Search   Previous   Next 

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.
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.

Contents   Index   References   Search   Previous   Next 
© 2005, 2006, 2007 John Barnes Informatics.
Sponsored in part by:
The Ada Resource Association and its member companies: ARA Members AdaCore Polyspace Technologies Praxis Critical Systems IBM Rational Sofcheck and   Ada-Europe:
Ada-Europe