CVS difference for ai05s/ai05-0145-2.txt
--- ai05s/ai05-0145-2.txt 2011/02/12 08:19:56 1.14
+++ ai05s/ai05-0145-2.txt 2011/02/16 06:15:23 1.15
@@ -1420,6 +1420,1485 @@
****************************************************************
+From: Robert Dewar
+Sent: Thursday, August 26, 2010 2:37 AM
+
+An issue comes up with the 'Old attribute
+
+GNAT has implemented this attribute for some time, and the definition in the AI
+is incompatible. This is a problem since it makes it difficult or impossible for
+us to implement the feature as described in the AI (since we don't want to
+introduce unnecessary incompatibilities in the move to Ada 2012).
+
+The issue is where to allow 'Old
+
+In GNAT, 'Old can be used anywhere in a subprogram body, or in a Postcondition
+or Precondition pragma that ends up in that subprogram body, for example, the
+following is legal:
+
+> 1. procedure p (x : in out integer) is
+> 2. procedure q (y : integer);
+> 3. pragma Precondition (y >= x'old);
+> 4.
+> 5. procedure q (y : integer) is
+> 6. begin
+> 7. null;
+> 8. end;
+> 9.
+> 10. begin
+> 11. q (x);
+> 12. if x /= x'old then
+> 13. raise Program_Error;
+> 14. end if;
+> 15. end;
+
+Tuck feels that the usage should be restricted to Post aspect expressions.
+
+First, for sure I think this should be allowed in assertion pragmas in the body.
+For general use, you can always define constants at the point of the subprogram
+entry (after all that is all the attribute does anyway), but that's not so good
+for the assert case, where you don't want the constants defined if assertions
+are disabled.
+
+Second, if the restriction is retained, I think we should consider using some
+name other than 'Old for the standard RM feature (perhaps Old_Value).
+
+Incompatibilities make me very nervous, the incompatibilites in the Ada 2005
+definition have very significantly delayed its adoption, and I don't want to see
+small things delay adoption of Ada 2012. It's not technically an incompatibility
+of course, but to define a new attribute with the same name as an attribute in
+wide use in Ada 2005 implementations with different semantics is in practice an
+incompatibility.
+
+If this is not changed, GNAT is faced with two possibilities:
+
+1. Ignore the restrictions in the RM, GNAT would still process all legal
+ programs correctly, but would fail to diagnose some illegal programs.
+
+2. Change the GNAT definition, which would create potential customer
+ incompatibilities. Note that for sure we would still allow its use in
+ precondition/postcondition macros, but I suppose that's marginally legal,
+ since we have total freedom in defining the syntax/semantics of our own
+ pragmas. It's uncomfortable for the expressions in those macros to have
+ different rules than expressions anywhere else.
+
+Probably we would choose approach 1, but it would end up being the one
+non-conformance, which would be a pity. In practice it would be harmless since
+there are unlikely to be any other Ada 2012 implementations around for a while.
+
+It's possible we would choose approach 2, but the ugly business with odd rules
+for precondition/postcondition pragmas are a problem, and I really see
+forbidding it in pragma Assert statements as a real likely source of
+incompatibilities in practice.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, August 26, 2010 8:08 AM
+
+Actually, I have no problem allowing 'Old in pragma Assert, and certainly no
+problem allowing it in implementation-defined pragmas.
+
+I don't like 'Old in non-assertion code, as it creates hidden overhead without
+obviously doing so, because a copy of the in-out parameter needs to be made
+implicitly. When it is inside a pragma Assert/Postcondition, or whatever, it is
+understood that such pragmas can be ignored in "production" mode. Clearly if
+'Old appears outside a pragma or Post aspect, it can't be ignored in production
+mode.
+
+Calling this an incompatibility is a bit of a stretch. This is an
+implementation-defined attribute in Ada 95 and Ada 2005. In Ada 2012, we
+happened to choose a name that an implementation is already using. The more
+common solution is for the implementation to adopt a new name, not for the
+language to have to work around the existence of an implementation-defined
+attribute. Clearly if 'Old becomes illegal outside pragmas or aspect clauses,
+your customers will learn about it quickly and can presumably adapt to a new
+name.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, August 26, 2010 8:27 AM
+
+> Actually, I have no problem allowing 'Old in pragma Assert, and
+> certainly no problem allowing it in implementation-defined pragmas.
+
+That helps a bit, probably in practice the majority of now-illegal uses are in
+assertions.
+
+> I don't like 'Old in non-assertion
+> code, as it creates hidden overhead without obviously doing so,
+> because a copy of the in-out parameter needs to be made implicitly.
+
+Doesn't seem very hidden to me (it is obvious that such a copy must be made to
+use this feature).
+
+And Ada is hardly a language where WYSIWYG when it comes to generated code (just
+define a tagged type and list the -gnatG output with GNAT!!!)
+
+I find this a very weak reason for "I don't like".
+If you don't like the effect of using 'Old in more general contexts, don't use
+it.
+
+But if you really want to talk about X'Old, it is much clearer to say X'Old, and
+much less verbiage than defining a constant without a fixed name and then using
+that.
+
+> Calling this an incompatibility is a bit of a stretch.
+
+Not for a user of the compiler! As I say I know that technically it is not an
+incompatibility, but in practice it IS an incompatibility for users of the
+compiler (which is all that counts in real life).
+
+> This is an implementation-defined
+> attribute in Ada 95 and Ada 2005. In Ada 2012, we happened to choose
+> a name that an implementation is already using.
+
+I think that it would be better to avoid using an existing attribute or pragma
+that is in wide use if you intend to change the meaning.
+
+> The more common solution is for the
+> implementation to adopt a new name, not for the language to have to
+> work around the existence of an implementation-defined attribute.
+
+But if we change the name, that's an incompatibility as well.
+
+> Clearly if 'Old becomes illegal outside pragmas or aspect clauses,
+> your customers will learn about it quickly and can presumably adapt to
+> a new name.
+
+Software folks never seem to understand the predicament of application engineers
+working with very large programs, that are under various stages of rigorous
+configuration control.
+
+If I decide to try out Ada 2012 and I get errors, I am uninclined to make the
+fix, it is potentially maor work to find the poeple who are allowed to make the
+changes to the affected units, do the necessary procedures for analyzing the
+changes, rerun affected unit tests etc etc etc.
+
+BTW the same goes for the very worrisome change in placement of user defined
+equality. Yes, of course it is nearly always fixable by moving the declaration,
+but again, the work of doing this move and verifying it is done right may be
+really major.
+
+New keywords like SOME are also problematical for the same reason.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, August 26, 2010 8:38 AM
+
+By the way, as of July 13, 2010 you can get Ada 2005 from IBM Rational as well,
+for what that's worth:
+
+ Apex 4.4.6 (Apex with Ada05) is available for download
+ ...
+ Size 608mb
+ Date posted 13-Jul-2010
+
+So I guess now there are two Ada 2005 compilers!
+Just in time for Ada 2012...
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, August 26, 2010 8:55 AM
+
+Right, that's why in my message I said "in wide use", if I had written this
+before July, I would have said "in all available Ada 2005 compilers" :-) :-)
+
+Anyway, it is great that Rational has released their Ada 2005 compiler, does
+anyone have information on how complete the implementation is?
+
+****************************************************************
+
+From: Steve Baird
+Sent: Saturday, August 28, 2010 12:24 AM
+
+Some additional (minor) points about this AI to consider:
+
+1) It appears that we allow pre and post conditions to be specified for a
+ non-abstract primitive subprogram of an interface type (which must be a null
+ procedure). It seems clear to me that this should be disallowed. Certainly
+ 8.3(12.3/2) assumes that null procedures with a given profile are pretty much
+ interchangeable and needs some changes if this is not the case.
+
+
+2) The AI currently contains the following wording:
+
+ For each X'Old in a postcondition expression that is enabled, a
+ constant is implicitly declared at the beginning of the subprogram or
+ entry, of the type of X, initialized to X.
+
+ I think this should be a permission; perhaps something like
+ "a constant may be implicitly declared".
+
+ Consider the following Post-Condition:
+
+ True or else Function_Call_With_Side_Effects'Old
+
+ There are other ways that X'Old can be dead, but it is
+ essentially the same problem:
+
+ Post_Condition => Some_Vector = Vector'(1.. 0 => X'Old)
+
+ The point is that an implementation should not have to check
+ a dead expression for uses of the Old attribute before
+ eliminating it. Nobody cares about performance in these
+ oddball cases - the issue is the unnecessary addition of
+ implementation complexity. There are similar issues if the
+ prefix of a 'Old attribute is a constant, or a function with
+ side-effects but a statically known result, or ...
+
+3)
+
+Tucker Taft wrote:
+ > Actually, I have no problem allowing 'Old
+ > in pragma Assert, and certainly no problem
+ > allowing it in implementation-defined pragmas.
+
+I think we would want
+ pragma Assert (X = T'(<expression>)'Old);
+to evaluate the attribute prefix upon entering the enclosing subprogram. This
+doesn't work if <expression> references declarations which don't exist at that
+point. It also doesn't work if the pragma doesn't occur within a subprogram. Not
+fundamental problems, but wording would be needed.
+
+Otherwise, what is the following supposed to mean:
+
+ procedure Foo is
+ X : Integer := 1;
+ begin
+ for I in 1 .. 10 loop
+ pragma Assert (X >= X'Old);
+ ...
+
+?
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Saturday, August 28, 2010 5:53 AM
+
+> I think we would want
+> pragma Assert (X = T'(<expression>)'Old); to evaluate the
+> attribute prefix upon entering the enclosing subprogram. This doesn't
+> work if <expression> references declarations which don't exist at that
+> point.
+
+That's a point indeed. In GNAT the rule is that 'Old can only reference
+parameters and global variables, it cannot reference local variables:
+
+> 1. procedure t (a : integer) is
+> 2. x : integer;
+> 3. y : integer := a + a;
+> 4. pragma Assert (a /= y'old);
+> |
+> >>> attribute "old" cannot refer to local variable "y"
+>
+> 5. begin
+> 6. null;
+> 7. end;
+
+The actual definition in GNAT currently is:
+
+> The attribute Prefix'Old can be used within a subprogram body or
+> within a precondition or postcondition pragma. The effect is to refer
+> to the value of the prefix on entry. So for example if you have an
+> argument of a record type X called Arg1, you can refer to
+> Arg1.Field'Old which yields the value of Arg1.Field on entry. The
+> implementation simply involves generating an object declaration which
+> captures the value on entry. Any prefix is allowed except one of a
+> limited type (since limited types cannot be copied to capture their
+> values) or an expression which references a local variable (since
+> local variables do not exist at subprogram entry time).
+
+
+> It also doesn't work if the pragma doesn't occur within a subprogram.
+
+Right, I certainly don't propose that
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, August 28, 2010 7:40 AM
+
+> 1) It appears that we allow pre and post conditions to be specified
+> for a non-abstract primitive subprogram of an interface type (which
+> must be a null procedure).
+> It seems clear to me that this should be disallowed.
+> Certainly 8.3(12.3/2) assumes that null procedures with a given
+> profile are pretty much interchangeable and needs some changes if this
+> is not the case.
+
+I don't see the problem. The pre/post conditions should be or'ed or and'ed as usual, then the null procedure does nothing. It might even be useful, once in a blue moon.
+
+> 2) The AI currently contains the following wording:
+>
+> For each X'Old in a postcondition expression that is enabled, a
+> constant is implicitly declared at the beginning of the subprogram or
+> entry, of the type of X, initialized to X.
+>
+> I think this should be a permission; perhaps something like
+> "a constant may be implicitly declared".
+
+I agree, but I think it might be easier to understand if we keep the current
+wording, then add a permission to omit that object if it's not needed. Similar
+to the way we allow omission of Finalize calls.
+
+> Consider the following Post-Condition:
+>
+> True or else Function_Call_With_Side_Effects'Old
+>
+> There are other ways that X'Old can be dead, but it is
+> essentially the same problem:
+>
+> Post_Condition => Some_Vector = Vector'(1.. 0 => X'Old)
+>
+> The point is that an implementation should not have to check
+> a dead expression for uses of the Old attribute before
+> eliminating it. Nobody cares about performance in these
+> oddball cases - the issue is the unnecessary addition of
+> implementation complexity. There are similar issues if the
+> prefix of a 'Old attribute is a constant, or a function with
+> side-effects but a statically known result, or ...
+
+Const'Old seems fishy -- maybe deserves a warning.
+
+> 3)
+>
+> Tucker Taft wrote:
+> > Actually, I have no problem allowing 'Old > in pragma Assert, and
+> certainly no problem > allowing it in implementation-defined >
+> pragmas.
+>
+> I think we would want
+> pragma Assert (X = T'(<expression>)'Old); to evaluate the
+> attribute prefix upon entering the enclosing subprogram. This doesn't
+> work if <expression> references declarations which don't exist at that
+> point.
+> It also doesn't work if the pragma doesn't occur within a subprogram.
+> Not fundamental problems, but wording would be needed.
+
+Right, we would need wording to disallow references to locals.
+
+> Otherwise, what is the following supposed to mean:
+>
+> procedure Foo is
+> X : Integer := 1;
+> begin
+> for I in 1 .. 10 loop
+> pragma Assert (X >= X'Old);
+> ...
+>
+> ?
+
+Should be illegal. It certainly should NOT mean "the value of X from last time
+around the loop"!
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, August 28, 2010 8:36 AM
+
+> 1) It appears that we allow pre and post conditions to be specified
+> for a non-abstract primitive subprogram of an interface type (which
+> must be a null procedure).
+> It seems clear to me that this should be disallowed.
+> Certainly 8.3(12.3/2) assumes that null procedures with a given
+> profile are pretty much interchangeable and needs some changes if this
+> is not the case.
+
+I'm not convinced of this. I think it is easy enough to combine the
+pre/post-conditions in an appropriate way when inherited, so that we don't need
+to make this restriction. Putting Post'Class on a null procedure of an
+interface makes some sense, if you want to specify, say:
+
+ Post'Class => Global = Global'Old
+
+to ensure that some overriding of the null procedure doesn't have some
+undesirable effect.
+
+...
+> Otherwise, what is the following supposed to mean:
+>
+> procedure Foo is
+> X : Integer := 1;
+> begin
+> for I in 1 .. 10 loop
+> pragma Assert (X >= X'Old);
+> ...
+>
+> ?
+
+Agreed, anything referenced in a blah'Old would have to be based on a parameter
+or be global to the subprogram. Basically, it would have to be well-defined at
+the point of the "is" of the enclosing subprogram body.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Saturday, August 28, 2010 12:31 PM
+
+> Actually, I have no problem allowing 'Old in pragma Assert, and
+> certainly no problem allowing it in implementation-defined pragmas.
+
+References to the 'Old attribute of a parameter should probably be disallowed
+from within a separate subunit, as in
+
+ procedure Foo (X : in out T) is
+
+ ....
+ ... Bar ... is separate;
+ begin ... end Foo;
+
+
+ separate (Foo)
+ ... Bar ... is
+ pragma Assert (Some_Predicate (X'Old));
+ ...
+ end Bar;
+
+If an implementation generates code for the parent before seeing the separate
+subunit body (as some implementations do), then implementing this case without
+distributed overhead would be difficult.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, August 28, 2010 1:03 PM
+
+> References to the 'Old attribute of a parameter should probably be
+> disallowed from within a separate subunit, as in
+
+It's only a problem in package subunits, right?
+
+It seems bad to disallow something in subunits that is allowed for a
+non-separate, because you might want to switch back and forth. That would argue
+for making it illegal immediately within a package body.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, August 28, 2010 1:40 PM
+
+Interesting issue.
+I agree, I guess.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Saturday, August 28, 2010 1:49 PM
+
+Interesting indeed, a very obscure case, but GNAT does indeed allow this, and of
+course we don't want a stupid thing like this to cause implementation
+difficulties in implementations with different models (and more importantly I
+think Rational has this different model??)
+
+I really dislike this special rule though, and Bob points out that it really has
+to be extended to any package body, not just subunits, for consistency. So we
+lose the nice simple rule anyway.
+
+HMMMM ....
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, August 28, 2010 2:30 PM
+
+I don't understand the issue with package bodies.
+Can you explain further?
+
+Now that I think more about Steve's example, I believe it should not actually be
+a problem, presuming expr'Old refers to the value of the expr at the entry to
+the immediately enclosing body, which should be required to be a subprogram or
+entry body. Hence in his example, X'Old refers to the value of X on entry to
+the nested subprogram.
+
+Doesn't that eliminate all subunit problems?
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Saturday, August 28, 2010 2:46 PM
+
+> I don't understand the issue with package bodies.
+
+It seems undesirable to ahve a situation where you can have a ppackage body
+within a subprogram, but you can't make it into a subunit, are there any other
+cases of such a restriction?
+
+> Can you explain further?
+>
+> Now that I think more about Steve's example, I believe it should not
+> actually be a problem, presuming expr'Old refers to the value of the
+> expr at the entry to the immediately enclosing body, which should be
+> required to be a subprogram or entry body. Hence in his example,
+> X'Old refers to the value of X on entry to the nested subprogram.
+>
+> Doesn't that eliminate all subunit problems?
+
+We are talking about a nested package, consider this example:
+
+procedure t (a : integer) is
+ x : integer;
+ y : integer := a + a;
+ package r is end;
+ package body r is separate;
+begin
+ null;
+end;
+
+separate (t)
+package body r is
+ pragma assert (a'old < 13);
+end r;
+
+GNAT allows this, rational would find it very hard to implement (the compile the
+package body truly separately, and we don't want a rule that makes this hard to
+do!)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, August 28, 2010 3:30 PM
+
+> I don't understand the issue with package bodies.
+> Can you explain further?
+
+I think maybe my e-mails to arg are getting stuck in the usual trap. They'll
+get through eventually, perhaps with some prodding from Randy.
+
+Anyway, my point is that if you have a physically nested package (or other
+thing), you might want to turn it into a subunit, or into a child unit. Or vice
+versa. The language should guarantee that that always works. It doesn't quite,
+but it almost does, so let's not make it worse.
+
+In this case, that implies that if we want to forbid 'Old in a package body
+subunit (of a subprogram), then we should also forbid 'Old in a non-separate
+package body within a subprogram.
+
+> Now that I think more about Steve's example, I believe it should not
+> actually be a problem, presuming expr'Old refers to the value of the
+> expr at the entry to the immediately enclosing body, which should be
+> required to be a subprogram or entry body.
+
+Yes, that's exactly the right rule.
+
+>...Hence in his example,
+> X'Old refers to the value of X on entry to the nested subprogram.
+
+I thought we were talking about subprograms that have package (or task?)
+subunits. Your rule above solves Steve's problem.
+
+If, on the other hand, you have a procedure with a procedure subunit, then of
+course a 'Old in the inner one refers to the state upon entry to the inner one
+-- that was never in question.
+
+> Doesn't that eliminate all subunit problems?
+
+Yes.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, August 28, 2010 3:54 PM
+
+> It seems undesirable to ahve a situation where you can have a ppackage
+> body within a subprogram, but you can't make it into a subunit, are
+> there any other cases of such a restriction?
+
+Yes. One example is:
+
+ procedure P is
+ procedure Q is
+ ...
+ package body R is separate; -- Illegal, but
+ -- putting the package body here would be OK.
+
+But that's pretty rare!
+
+Maybe that case doesn't count -- if you say "procedure Q is separate"
+it works. And I can't think of any other cases where replacing a proper body
+with a subunit doesn't work.
+
+Ideally, it would always be possible to switch back and forth between separate
+compilation and non-separate compilation of packages (whether for subunits or
+library units).
+
+Going the other direction (subunit to physically nested unit), there's a
+different obscure problem -- with/use clauses on the subunit need to be moved to
+the top of the parent unit, and that can cause illegality.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Saturday, August 28, 2010 6:52 PM
+
+> I'm not convinced of this. I think it is easy enough to combine the
+> pre/post-conditions in an appropriate way when inherited, so that we
+> don't need to make this restriction. Putting Post'Class on a null
+> procedure of an interface makes some sense, if you want to specify,
+> say:
+>
+> Post'Class => Global = Global'Old
+>
+> to ensure that some overriding of the null procedure doesn't have some
+> undesirable effect.
+>
+
+I think you misunderstood me (possibly because I was unclear).
+I was talking about the Pre and Post aspects, not the Pre'Class and Post'Class
+aspects.
+
+With regard to the Pre'Class and Post'Class aspects, I agree with you about how
+we want the language to work. We may need to look carefully at the wording to
+verify that this case is handled correctly.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Sunday, August 29, 2010 7:09 PM
+
+> Actually, I have no problem allowing 'Old in pragma Assert, and
+> certainly no problem allowing it in implementation-defined pragmas.
+
+Well, I do have a problem with allowing it in language-defined stuff that is not
+in the subprogram header. (Obviously, I don't care about implementation-defined
+pragmas.)
+
+Janus/Ada is essentially a one-pass compiler so far as semantics is concerned.
+'Old requires code to be generated at the "is" of the subprogram. If 'Old is
+allowed outside of the subprogram header (that is, in the aspect clause), we
+would have no way to know whether any code is needed. Typically, such cases are
+handled by adding thunks, which would mean this feature would have a distributed
+overhead (every subprogram would need a thunk call at the top since there would
+be no way to know ahead of time whether 'Old appears in an Assert pragma at some
+later point).
+
+The net effect is that a general 'Old would add a significant expense to every
+subprogram call in Janus/Ada. Which is simply unacceptable; I doubt that I would
+implement it if that is the case.
+
+
+A second point is that I object to making the contents of pragma Asserts
+different in some material way than regular code. I personally never use pragma
+Assert as it does not have enough control over when it is or is not executed. My
+experience (in our projects, YMMV) is that a dynamic method of controlling this
+sort of code is needed. That necessary if the check is expensive enough to be a
+significant drag on performance (if it is cheap, it should always be done so
+there is no need to be able to turn it off -- many of the worst bugs in our
+compiler have come where cheap checks were eliminated for a false efficiency).
+
+The self-checks in our code usually look something like:
+
+ if Trace_Manager(<Some_Trace_Enumeration>) and then (not <check expression>) then
+ Internal_Error (<Some message>);
+ end if;
+
+Trace_Manager is usually a function controlled from a run-time menu; but if
+minimum-sized code is needed, the function is replaced by a constant aggregate
+with all values False. Then dead code elimination removes all of the code
+overhead of the checks.
+
+I would find it very annoying if this technique could not be used to replace an
+existing pragma Assert, or that you would be forced to use pragma Assert instead
+of writing some more effective code. That argues for either the restriction in
+the AI, or allow using anywhere in the subprogram body (but of course that runs
+afoul of my first concern).
+
+(I still believe that dynamic pragmas like pragma Assert are an abuse of the
+intent of the language [one that the Ada 95 team made part of the language], and
+I am automatically against anything that would require expanding their use.)
+
+
+If we are going to make any substantive changes to this attribute, I ask that we
+reopen the AI so that all of the issues (and Steve had some as well) can be
+properly discussed. (And I'd like to know if we're going to do that ASAP,
+because this AI is the last thing I need to add to the AARM before starting the
+review; if we're reopening it, I can start the review right away).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, August 29, 2010 8:16 PM
+
+GNAT already has a pragma Check, I believe, which is roughly equivalent to
+Assert but has a bit more flexibility. Perhaps we should simply suggest that
+GNAT limit the use of 'Old to their implementation-defined pragmas, such as
+Check and Postcondition, and then other implementors don't need to worry about
+it.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Sunday, August 29, 2010 9:54 PM
+
+I would be inclined to continue to recognize 'Old in Assert pragmas in GNAT,
+otherwise I think we would be introducing an unacceptable incompatibility and it
+really does not matter if GNAT fails to diagnose the "error" of using 'Old in an
+assert pragma (there are zillions of ways in GNAT of introducing non-portability
+using the large number of implementation defined pragmas and attributes so one
+more is no big deal).
+
+I find the argument that Randy has trouble implementing it in his compiler weak.
+The implementation model he has chosen is inappropriate and very limiting. In
+any case here you only get the distributed overhead if assertions are enabled,
+so that's not too bad.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Sunday, August 29, 2010 9:59 PM
+
+BTW, I think it is no big deal if Randy's compiler fails to allow 'Old in assert
+pragmas. Also I find Randy's attitude to pragma assert plain bizarre (this
+pragma is VERY widely and heavily used throughout the GNAT sources, and many of
+our customers use it widely).
+
+****************************************************************
+
+From: Steve Baird
+Sent: Monday, August 30, 2010 2:50 AM
+
+More thoughts to consider.
+
+ 1) If a "Old attribute occurs within the prefix of another, as in
+
+ F (G (X)'Old)'Old
+
+ this requires that the implicitly declared constant for the
+ inner 'Old must precede that for the outer but the AI says
+ "These implicit declarations occur in an arbitrary order".
+
+ Perhaps all that is needed here is an AARM "to be honest"
+ note saying that the order isn't really 100% arbitrary.
+ Or perhaps this is such an angels-on-the-head-of-a-pin
+ issue that we can just ignore it.
+
+ Incidentally, I think that X'Old'Old is legal. I don't see
+ that this situation is any different then the example above -
+ the initial value for one implicitly declared constant
+ includes a reference to another such constant.
+
+ 2) I think we want to disallow at least some allocators within
+ the prefix of a 'Old attribute in order to avoid having to
+ talk about these implicit constant declarations in the
+ definitions of "master" and/or "accessibility level"
+
+ If this example
+ function F (X : access Some_Task_Type) return Boolean is .... ;
+
+ procedure Foo is
+ begin
+ ...;
+ pragma Assert (F (new Some_Task_Type)'Old);
+
+ were allowed, then I think extra wording would be needed in
+ order to ensure that this was equivalent to
+
+ procedure Foo
+ Temp : constant Boolean := F (new Some_Task_Type);
+ begin
+ ...;
+ pragma Assert (Temp);
+
+ And who really wants to work out the consequences (either for the
+ RM or for their favorite compiler) of allowing
+ a 'Old prefix to include the creation of a coextension? Anyone
+ who didn't take two steps backward just volunteered.
+
+3)
+
+Tucker Taft writes:
+ > Actually, I have no problem allowing 'Old in pragma Assert,
+ > and certainly no problem allowing it in
+ > implementation-defined pragmas.
+
+It seems a bit odd that transforming
+
+ begin
+ -- identifiers P1 and P2 occur nowhere in this block
+ <stmt>1;
+ <stmt>2;
+ <stmt>3;
+ <stmt>4;
+ end;
+
+ into
+
+ declare
+ procedure P1 is
+ begin
+ <stmt>1;
+ <stmt>2;
+ end P1;
+ procedure P2 is
+ begin
+ <stmt>3;
+ <stmt>4;
+ end P2;
+ begin
+ P1;
+ P2;
+ end;
+
+would no longer be semantics-preserving (e.g. if <stmt>3 contains
+Some_Expression'Old). Tools that implement this sort of refactoring would have
+to be aware of this issue. Users who wrap subprograms around large blocks of
+code may be unpleasantly surprised. This is not a fundamental objection - just
+an observation. [and yes, I know that the above transformation wasn't always
+semantics-preserving in Ada05 even if both versions compiled successfully, but
+those cases were pretty pathological - the one I'm thinking of involves the
+Address attribute of a label].
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, August 30, 2010 5:01 AM
+
+...
+> Incidentally, I think that X'Old'Old is legal. I don't see
+> that this situation is any different then the example above -
+> the initial value for one implicitly declared constant
+> includes a reference to another such constant.
+
+This is definitely angels on a pin!
+'Old'Old is stupid, never useful, never worth bothering about IMO
+
+...
+> And who really wants to work out the consequences (either for the
+> RM or for their favorite compiler) of allowing
+> a 'Old prefix to include the creation of a coextension? Anyone
+> who didn't take two steps backward just volunteered.
+
+Yes, just outlaw allocators alltogether if it makes someone more confident,
+whether the compiler will bother with this check when there are lots more
+important things to do??? :-) :-)
+
+...
+> would no longer be semantics-preserving (e.g. if <stmt>3 contains
+> Some_Expression'Old). Tools that implement this sort of refactoring
+> would have to be aware of this issue. Users who wrap subprograms
+> around large blocks of code may be unpleasantly surprised. This is not
+> a fundamental objection - just an observation. [and yes, I know that
+> the above transformation wasn't always semantics-preserving in Ada05
+> even if both versions compiled successfully, but those cases were
+> pretty pathological - the one I'm thinking of involves the Address
+> attribute of a label].
+
+This is worrying too much, there are LOTS of cases where such refactoring does
+not work, e.g. return statements and requeue statements! not to mention goto
+statements :-)
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, August 30, 2010 5:03 AM
+
+One thing one could say is that if the prefix of 'Old involves ANY side effects
+of ANY kind, then the effect is implementation dependent (this takes care of the
+business of not generating the copy if the compiler can tell that the 'Old is
+not needed.
+
+In practice, for me 100% of the uses of 'Old are simple variable references, and
+I would not mind this restriction!
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, August 30, 2010 6:01 AM
+
+> One thing one could say is that if the prefix of 'Old involves ANY
+> side effects of ANY kind, then the effect is implementation dependent
+> (this takes care of the business of not generating the copy if the
+> compiler can tell that the 'Old is not needed.
+
+OK with me, I suppose, but this might lead to an endless discuss about what
+constitutes "side effect".
+
+> In practice, for me 100% of the uses of 'Old are simple variable
+> references, and I would not mind this restriction!
+
+We had this discussion (on ada-comment@, I think). I am strongly opposed to
+such an onerous restriction. I certainly want to allow function calls.
+
+But I'd be happy to forbid alligators (in the 'Old -- we're not going to forbid
+allocators in functions called).
+
+By the way, why don't we fix the syntax to allow:
+
+ (X + Y)'Old
+
+I mean, for all attributes. It's really stupid that that's not allowed, but
+these:
+
+ "+"(X, Y)'Old
+ My_Integer'(X + Y)'Old
+
+are allowed.
+
+(Let's see if this e-mail gets through without Randy doing some magic by hand.)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, August 30, 2010 5:07 AM
+
+> Incidentally, I think that X'Old'Old is legal.
+
+X'Old'Old = X'Old, right?
+
+> And who really wants to work out the consequences (either for the
+> RM or for their favorite compiler) of allowing
+> a 'Old prefix to include the creation of a coextension? Anyone
+> who didn't take two steps backward just volunteered.
+
+Consider me back-stepped.
+
+> It seems a bit odd that transforming
+>
+> begin
+> -- identifiers P1 and P2 occur nowhere in this block
+> <stmt>1;
+> <stmt>2;
+> <stmt>3;
+> <stmt>4;
+> end;
+>
+> into
+>
+> declare
+> procedure P1 is
+> begin
+> <stmt>1;
+> <stmt>2;
+> end P1;
+> procedure P2 is
+> begin
+> <stmt>3;
+> <stmt>4;
+> end P2;
+> begin
+> P1;
+> P2;
+> end;
+>
+> would no longer be semantics-preserving (e.g. if <stmt>3 contains
+> Some_Expression'Old).
+
+This doesn't seem SO bad.
+
+What about finalization? Moving things into a nested procedure can make them
+finalize early.
+
+What if P1 is "if Blah then return; end if;"?
+
+Seems like there are various ways in which the above transformation doesn't
+quite work, so one more isn't a disaster.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, August 30, 2010 12:16 PM
+
+I've come around to thinking that 'Old should only be defined as usable in Post
+and Post'Class aspects, and let implementors support it if they want in their
+own implementation-defined pragmas inside bodies (and/or cheat and support it in
+standard pragmas as well). I don't think we should waste verbiage in the
+standard trying to define what 'Old means in an arbitrary Assert pragma.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Monday, August 30, 2010 2:39 PM
+
+>> Incidentally, I think that X'Old'Old is legal.
+>
+> X'Old'Old = X'Old, right?
+
+Typically, yes.
+
+If controlled types are involved, this wouldn't strictly have to be true,
+
+> What if P1 is "if Blah then return; end if;"?
+>
+> Seems like there are various ways in which the above transformation
+> doesn't quite work, so one more isn't a disaster.
+
+Agreed.
+
+Incidentally, I think that my fears about accessibility/master complications for
+allocators may extend to other object-creating constructs (at least aggregates;
+I'm not sure about function calls).
+
+Is there any need for a more detailed exploration of this?
+
+When we have rules based on the enclosing whatever and then we invent an
+attribute which introduces an implicit declaration which is supposed to behave
+as though it syntactically encloses the attribute prefix, it does not seem
+surprising that we would have to describe this interaction in the rules
+somewhere.
+
+I'd prefer to see some clean, simple restrictions (perhaps on the form of the
+expressions, perhaps on their placement) which would spare us from dealing with
+this stuff.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, August 30, 2010 5:53 PM
+
+> I've come around to thinking that 'Old should only be defined as
+> usable in Post and Post'Class aspects, and let implementors support it
+> if they want in their own implementation-defined pragmas inside bodies
+> (and/or cheat and support it in standard pragmas as well). I don't
+> think we should waste verbiage in the standard trying to define what
+> 'Old means in an arbitrary Assert pragma.
+
+At this stage, that sounds reasonable to me! Although I would be happier if the
+name did not clash with the incompatible GNAT implementation, but perhaps 'Old
+is the only good name in the world? :-)
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, August 30, 2010 5:54 PM
+
+> We had this discussion (on ada-comment@, I think). I am strongly
+> opposed to such an onerous restriction. I certainly want to allow
+> function calls.
+
+Hard to imagine a situation where F(X'Old) is not an OK substitute for F(X)'Old.
+I really dislike calling functions with side effects in a situation like this.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, August 31, 2010 12:07 AM
+
+...
+> Incidentally, I think that my fears about accessibility/master
+> complications for allocators may extend to other object-creating
+> constructs (at least aggregates; I'm not sure about function calls).
+>
+> Is there any need for a more detailed exploration of this?
+
+I'm afraid so. We spent a lot of effort in Ada 2005 dealing with masters of
+function calls to explain what happens for tasks and controlled created in
+return objects then passed to another function call and other such silly things.
+
+Robert will say (correctly) that no one would ever do any of these things in the
+prefix of the 'Old attribute, but that doesn't absolve the Standard from
+explaining what happens if someone does. (And I don't think
+implementation-defined works; we've never done that for any issue involving
+masters and it would seem bizarre to start with this feature.)
+
+> When we have rules based on the enclosing whatever and then we invent
+> an attribute which introduces an implicit declaration which is
+> supposed to behave as though it syntactically encloses the attribute
+> prefix, it does not seem surprising that we would have to describe
+> this interaction in the rules somewhere.
+>
+> I'd prefer to see some clean, simple restrictions (perhaps on the form
+> of the expressions, perhaps on their placement) which would spare us
+> from dealing with this stuff.
+
+The only "clean, simple" restriction that I can think of is objects (and
+literals) only, and Bob has already said that isn't acceptable to him.
+Perhaps that could be extended a bit to allow predefined operators, but I don't think we can allow arbitrary function calls if we want to avoid this mess.
+
+OTOH, I'm not sure I really understand why Bob wants function calls in the
+prefixes of these attributes, since that seems to be an abuse of the intended
+functionality, which is to give access to the initial values of formal
+parameters -- ain't no function calls in formal parameters. So perhaps these
+restrictions are acceptable (as always, it is easier to relax restrictions in
+future versions of the language than to add them if they prove to be needed).
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, August 31, 2010 3:18 AM
+
+> OTOH, I'm not sure I really understand why Bob wants function calls in
+> the prefixes of these attributes, since that seems to be an abuse of
+> the intended functionality, which is to give access to the initial
+> values of formal parameters --
+
+or globals .. if the purpose of a procedure call is to modify some global
+variables, it is quite reasonable to have post conditions that test that the
+right thing has been done to them using 'Old.
+
+> ain't no function calls in formal parameters. So perhaps these
+> restrictions are acceptable
+
+To me they are certainly acceptable. If you have a situation where
+
+ F(X)'Old and F (X'OLd)
+
+are different, it means that F is a nasty impure function. I don't think impure
+functions are nasty in general, but I sure do thing that using functions with
+side effects or other impurities is bad form in a postcondition in any case, let
+alone in the prefix of 'Old!
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, August 31, 2010 12:45 AM
+
+[Slightly off-topic, and I know I should let this go, but...]
+
+From Robert Dewar:
+> BTW, I think it is no big deal if Randy's compiler fails to allow 'Old
+> in assert pragmas. Also I find Randy's attitude to pragma assert plain
+> bizarre (this pragma is VERY widely and heavily used throughout the
+> GNAT sources, and many of our customers use it widely).
+
+I think the fact that customers use it widely is simply because if you give
+someone a hammer, a lot of problems start to look like a nail. (That is, it is
+used because it is there.) It simply doesn't provide enough for the projects
+I've worked on, and I usually find that it is better to use "regular" Ada code
+to handle these sorts of checks. There are a number of reasons for this:
+
+(1) I don't find that binary on/off is sufficient. There is often a need to
+ partition the program into multiple parts for testing/debugging purposes.
+ (This was especially true back in the bad old days of MS-DOS, with very
+ little memory available.) AdaCore seems to have recognized this, given the
+ invention of pragma Check in GNAT.
+
+(2) In addition, I find that some of these checks are too expensive to leave on
+ all of the time, and recompiling to turn them on and off is a significant
+ pain. (Again, this was worse in the past than it is now; builds don't take
+ two hours anymore.) Moreover, there is a similar pain for tracing/logging
+ support. Tracing/logging tends to get a runtime manager UI of some sort in
+ my programs for control/ease-of-debugging; once that exists, it makes sense
+ to use it (rather than pragma Assert) to control expensive checks.
+
+(3) I'm in the camp of turning off checks is like
+ using-seatbelts-only-in-the-garage. So I don't see much reason to make it
+ possible to eliminate cheap checks. Where we used to do that to save space
+ in very early Janus/Ada compilers almost always seemed to lead to regrets
+ down the road. One common example is the "dangling else", where after
+ testing a bunch of conditions, we're left with an else case that doesn't
+ seem to have an logical reason to exist. These days, I always try to stick
+ an internal error into such cases, because they seem to get executed a lot
+ more often than one would think, and simply ignoring them simply postpones a
+ problem to a place where it is later much harder to find. So there is no
+ need for pragma Assert in cases like this; the check should never be turned
+ off and has little or no runtime cost unless there is a bug anyway.
+
+(4) Pragma Assert only takes expressions, and that is too limiting for many
+ tasks (Ada 2012 will mitigate this somewhat). If you have to write a support
+ function, you've lost the ability to remove it easily (as it is not clearly
+ part of the asserts).
+
+(5) In Janus/Ada at least, dead code elimination is very effective and little
+ vestige of unused code is left behind (that's a consequence of our
+ memory-limited days). I expect that most modern compilers are similar. There
+ isn't much need for a special feature that does what the compiler will do
+ anyway (given an appropriate False expression, as explained in my original
+ message on this subject). Pragma Assert doesn't help much with the real
+ difficult problem of dead global data elimination (given that it only works
+ on expressions).
+
+(6) Finally, I think that the use of pragmas for runtime evaluation of things is
+ an abuse of the concept as intended by Ada 83. I realize Ada 95 added a
+ number of these things; I argued against them at the time (and obviously
+ lost) and have not changed my opinion on that. Ada 2012 finally has a proper
+ way to do things like pragma Priority; while we're obviously not going to
+ get rid of any of the existing ones, we can finally move them to the dustbin
+ in which they belong -- and thus anything that gives them more promenence is
+ a bad idea IMHO.
+
+Honestly, the only one of these things that can be considered "bizarre" is the
+last, and even it is grounded in early Ada standards.
+
+As I said, all of this comes from *my experience* with various systems.
+Surely other sorts of systems have different requirements, so I can surely
+believe that someone else finds more use for pragma Assert than I do. Even so, I
+don't find it a very important part of Ada.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, August 31, 2010 9:54 AM
+
+If we're really going to rehash this argument, we all ought to look at the old
+'Old discussions! ;-)
+
+> To me they are certainly acceptable. If you have a situation where
+>
+> F(X)'Old and F (X'OLd)
+>
+> are different, it means that F is a nasty impure function.
+
+I don't think that's true (see (*) below).
+
+>...I don't think impure functions are nasty in general, but I sure do
+>thing that using functions with side effects or other impurities is
+>bad form in a postcondition in any case, let alone in the prefix of
+>'Old!
+
+I basically agree with your attitude toward side effects.
+(Not sure what "other impurities" means.) But I think this isn't the point.
+
+I think F(X)'Old is more readable than F(X'Old).
+This becomes more apparent when referring to multiple params/globals: F(X,
+Y)'Old is better than F(X'Old, Y'Old). I'd rather say:
+
+ (((X**2) + (Y**2)) / Z)'Old
+
+than:
+
+ (((X'Old**2) + (Y'Old**2)) / Z'Old)
+
+I realize I have to say:
+
+ My_Type'(((X**2) + (Y**2)) / Z)'Old
+
+which is annoying, but still preferable to sprinkling 'Old on all the variables.
+
+Suppose somebody says:
+
+ (((X'Old**2) + (Y'Old**2)) / Z)
+
+Is that a bug (forgot 'Old on Z)? Or is Z constant, so it doesn't need 'Old?
+Or is Z a variable, but it doesn't get modified by this procedure, so doesn't
+need 'Old? This analysis requires a lot of thought, which is completely
+obviated by putting 'Old on the whole expression. (And I think I'd like a
+warning if 'Old is applied to an expression whose value couldn't possibly have
+changed since the start of the procedure.)
+
+Efficiency issue: Consider F(X, Y)'Old. Suppose X and Y are giant records, and
+F returns Integer. You really don't want to save copies of the giant records --
+you want to save a copy of that Integer.
+
+(*) As to my claim above: A long time ago, Randy gave a good example why.
+Reference-counted (controlled) type. We want to refer to Count(X)'Old. That
+saves the old value of the reference count. We do NOT want Count(X'Old), because
+that saves the old value of X, which involves calling Adjust, thus MODIFYING the
+ref count. It is precisely to AVOID that side effect that we want Count(X)'Old.
+In other words, your claim (with which I agree), "side effects [are] bad form
+... in the prefix of 'Old!" argues for allowing Count(X)'Old.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, August 31, 2010 11:12 AM
+
+> ... , but that doesn't absolve the Standard from explaining what
+> happens if someone does [do these oddball things].
+
+Agreed.
+
+> The only "clean, simple" restriction that I can think of is objects (and
+> literals) only, and Bob has already said that isn't acceptable to him.
+> Perhaps that could be extended a bit to allow predefined operators,
+> but I don't think we can allow arbitrary function calls if we want to
+> avoid this mess.
+
+I don't see any problem with allowing calls to most (but see Has_Polka_Dots
+below) elementary-valued functions. But then where do you draw the line?
+
+Are there problems if the type of the 'Old attribute is anonymous, as in
+
+ Param.Array_Of_Limited_Discriminated(I).Access_Discriminant'Old
+or
+ Has_Polka_Dots (Anon_Access_Param =>
+ Param.Array_Of_Aliased(I)'Access'Old)
+?
+
+We are certainly stretching the model here:
+ For each X'Old in a postcondition expression that is enabled, a
+ constant is implicitly declared at the beginning of the subprogram or
+ entry, of the type of X, initialized to X.
+
+What is the type of this constant for these examples?
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, August 31, 2010 11:21 AM
+
+> I don't see any problem with allowing calls to most (but see
+> Has_Polka_Dots below) elementary-valued functions.
+
+Correction: please ignore the above reference to the Has_Polka_Dots example.
+In that example, the function call did not occur as part of the prefix of the
+'Old attribute. Oops.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, August 31, 2010 1:38 PM
+
+> > The only "clean, simple" restriction that I can think of is objects
+> > (and
+> > literals) only, and Bob has already said that isn't acceptable to him.
+
+Well, "acceptable" is a bit strong. I'm not the boss, just one ARG member
+trying convince the rest that we don't need these restrictions we are
+discussing. And anything that forbids calls is suspect, because calls are the
+main tool of abstraction in Ada (or any other language).
+
+> I don't see any problem with allowing calls to most (but see
+> Has_Polka_Dots below) elementary-valued functions.
+
+I still don't see why we need restrictions. Why do you say "elementary"?
+(Sorry if I'm being dense!)
+
+(We do need a restriction forbidding 'Old applying to a package body.)
+
+> But then where do you draw the line?
+>
+> Are there problems if the type of the 'Old attribute is anonymous, as
+> in
+>
+> Param.Array_Of_Limited_Discriminated(I).Access_Discriminant'Old
+> or
+> Has_Polka_Dots (Anon_Access_Param =>
+> Param.Array_Of_Aliased(I)'Access'Old)
+> ?
+>
+> We are certainly stretching the model here:
+> For each X'Old in a postcondition expression that is enabled, a
+> constant is implicitly declared at the beginning of the subprogram or
+> entry, of the type of X, initialized to X.
+>
+> What is the type of this constant for these examples?
+
+For the first, can't we say the type is "access Blah"?
+I.e. a different anon access type, and if that causes illegality/weirdness due
+to accessibility, then so be it. (I realize the current wording doesn't quite
+say that. And I could live with a "no anon access" rule, since I hate anon
+access anyway.)
+
+For the second example, well you withdrew that in a subsequent message.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, August 31, 2010 2:01 PM
+
+> For the second example, well you withdrew that in a subsequent
+> message.
+
+I didn't withdraw the example. I just noted that it had no bearing on the
+question of whether function calls are ok as part of the prefix of a 'Old
+attribute. Nonetheless, I think your comments about the 1st apply equally well
+to the 2nd - we could support this or forbid it but the existing wording needs a
+little work in either case.
+
+> I still don't see why we need restrictions. Why do you say
+> "elementary"?
+
+If a function call returns an elementary result, then there is no way that we
+care about the accessibility level or the master of the function result object.
+If it returns a composite result (e.g., a result with task components,
+controlled components, and aliased components), then perhaps we do care. We
+would like to avoid having to define the accessibility level or the master in
+these cases, so (I think) we would like to avoid constructs which would require
+such a definition.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, August 31, 2010 9:57 AM
+
+> ...
+> > Incidentally, I think that my fears about accessibility/master
+> > complications for allocators may extend to other object-creating
+> > constructs (at least aggregates; I'm not sure about function calls).
+> >
+> > Is there any need for a more detailed exploration of this?
+>
+> I'm afraid so. ...
+
+I don't understand what the problem is.
+
+'Old is defined by putting an implicit constant decl at the start of the
+procedure. That equivalence should explain what the
+accessibility/master/blah/blah/blah rules are. No need to state them explicitly
+in the RM. And no need for the compiler to do anything special -- just apply the
+normal semantic analysis to that implicit decl.
+
+Yesterday, Steve got me all frightened about coextensions and whatnot in
+prefixes 'Old. But now I think there's nothing to be afraid of.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, August 31, 2010 10:08 AM
+
+> At this stage, that sounds reasonable to me! Although I would be
+> happier if the name did not clash with the incompatible GNAT
+> implementation, but perhaps 'Old is the only good name in the world?
+> :-)
+
+I really don't like the idea of having both 'Old and 'Old_Value existing in the
+world, with subtly different rules, and people not being able to remember which
+of them are standard vs. compiler specific.
+
+I don't buy Tuck's argument against 'Old in arbitrary code.
+It's basically the WYSIWYG-for-efficiency argument, and I rarely buy that. I
+mean, this is a language where "X: T;" might just allocate 4 bytes in the stack
+frame and do nothing else. Or, it might do all kinds of default initialization,
+then later fire up some tasks, then later do finalization, with abort deferral
+and so on. And that's a good thing!
+
+WYSIWYG is exactly the opposite of high-level language design.
+If you want WYSIWYG, use assembly language.
+
+So my preferred rule is that 'Old applies to the innermost body, and that body
+must be a subprogram or entry. No requirement that it be inside certain
+pragmas.
+
+If I can't convince folks of that, then I'd prefer GNAT change its handling of
+'Old to include the arbitrary restrictions in the RM. For compatibility, GNAT
+can eliminate these restrictions in -X (allow extensions) mode.
+
+Yes, 'Old "is the only good name in the world". ;-) Please don't invent
+'Old_Value. 'Old is the perfect name.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, September 1, 2010 3:23 PM
+
+>> To me they are certainly acceptable. If you have a situation where
+>>
+>> F(X)'Old and F (X'OLd)
+>>
+>> are different, it means that F is a nasty impure function.
+>
+> I don't think that's true (see (*) below).
+
+
+OK, these are convincing arguments!
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, September 8, 2010 9:44 AM
+
+Just to summarize what I think the consensus was on some issues (and this is
+what GNAT has implemented :-))
+
+We keep the oring of inherited Pre'Class aspects, and if there is a Pre'Class
+for the current subprogram it is also Or'ed in. [GNAT has a nice exception
+message which shows all the preconditions that have failed if the or fails.]
+
+We do not allow the Pre aspect if there is an explicit Pre'Class or any
+inherited Pre'Class. This avoids the confusion that happens with Or'ing
+Pre'Class stuff where it is expected, and Pre stuff (where it probably is not)
+
+For Post, we have no restrictions, Post and Post'Class can both be specified and
+just get and'ed with any inherited Post'Class aspects. The idea is that no
+confusion arises in this case, and it is harmless to pile up postconditions (and
+may well be useful).
+
+****************************************************************
+
From: Florian Weimer
Sent: Saturday, September 25, 2010 2:41 PM
Questions? Ask the ACAA Technical Agent