!standard 9.6.1(70/2) 11-06-12 AI05-0249-1/01 !class pathology 11-06-12 !status work item 11-06-12 !status received 11-05-12 !priority Low !difficulty Easy !subject AI05-0130-1 should be a pathology !summary Reclassify AI05-0130-1 as a pathology. !question AI05-0130-1 says that no ACATS test should be constructed to test this behavior. If that is the case, we should clearly say that this is a pathology to indicate to future readers that this behavior is not to be depended upon. !recommendation (See Summary.) !wording None needed. !discussion Bob doesn't like AI05-0130-1, but the alternatives seem worse. (See AI05-0130-1 for a detailed discussion.) !ACATS test None for pathologies. !appendix From: Bob Duff Sent: Thursday, May 12, 2011 8:54 AM I think AI05-0130-1, Order of initialization/finalization of record extension components, should be reconsidered. This AI requires that, in rare cases, a component of an extension part be initialized after components of the parent part, and, if controlled, be finalized before components of the parent part. This is a ramification. It is indeed what the RM says, but I'm pretty sure that if Tuck and I had noticed this ramification during 9X, we would have fixed it. I suspect ARG passed this without thinking through the implementation difficulties, and user confusions. I suspect all Ada 2012 compilers do not obey this AI. This AI is harmful, because: Hard to implement if you have to mix initialization/finalization of extension components with those of the parent. Even harder to implement if you want to be most efficient (i.e. keep the current mechanism in the 99.9% of cases where it works). Complicates an already-too-complicated area. Causes a confusing order for users (programmers expect bottom-up initialization and top-down finalization). And can cause uninit-var bugs (better to stick with the bugs we have, than to switch to different bugs!) -- that is, it's the worst flavor of incompatibility. By the way, note that the issue is not just for controlled types. Any type can have initializations. **************************************************************** From: Dan Eilers Sent: Thursday, May 12, 2011 11:22 AM > I suspect all Ada 2012 compilers do not obey this AI. Our compiler obeys this AI. > And can cause > uninit-var bugs (better to stick with the bugs we have, than to switch > to different bugs!) -- that is, it's the worst flavor of incompatibility. This "worst flavor" incompatibility is what currently occurs when users switch between compilers. **************************************************************** From: Bob Duff Sent: Thursday, May 12, 2011 11:37 AM > > I suspect all Ada 2012 compilers do not obey this AI. > > Our compiler obeys this AI. Interesting. I guess that makes sense, since you submitted the original question. > > And can cause > > uninit-var bugs (better to stick with the bugs we have, than to > > switch to different bugs!) -- that is, it's the worst flavor of incompatibility. > > This "worst flavor" incompatibility is what currently occurs when > users switch between compilers. True. If I were in charge, I would have required a certain order -- I don't see any advantage to allowing compiler variations in this area. But it's too late for that now. Perhaps we should allow some implementation freedom here. For GNAT, it really is a lot of trouble to "mix" the parent and extension fields. And we don't want subtle incompatibilities between versions of GNAT, even if that can't be helped between Eilers' compilers and AdaCore's compilers. **************************************************************** From: Robert Dewar Sent: Thursday, May 12, 2011 11:37 AM >> I suspect all Ada 2012 compilers do not obey this AI. > > Our compiler obeys this AI. But is not currently a full Ada 2012 compiler, or is it??? >> And can cause >> uninit-var bugs (better to stick with the bugs we have, than to >> switch to different bugs!) -- that is, it's the worst flavor of >> incompatibility. > > This "worst flavor" incompatibility is what currently occurs when > users switch between compilers. Yes, but in the case of GNAT, we would be introducing this "worst flavor" incompatibility for gnat users who update to Ada 2012, that would be really horrible, definitely not worth it, and definitely much more damaging than a theoretical issue with moving between GNAT and as yet non-existent other Ada 2012 compilers! This is simply not something that is worth putting in the way of people moving to Ada 2012. Mind you, it's horrible style to write code that cares about this, and it would not surprise me if no one runs into this in practice. But all the more reason for not wasting time completley redesigning a large part of GNAT for the purpose of intrducing unwanted portability and compatibility problems. After all this "worst flavor" incomaptibility occurs whenever anyone writes horrible code that depends on the order of things, since in Ada we leave order of evaluation impl dependent (not even impl defined) in many kmany cases. In practice, it is a minimal source of incompatibilites (compared with representation and layout issues for example, where people depend on default alignment etc choices, and compared with elaboration issues, where people routinely have only enough pragma Elaborate's to guarantee ok behvaior on some previous compiler). **************************************************************** From: Dan Eilers Sent: Thursday, May 12, 2011 12:02 PM > But is not currently a full Ada 2012 compiler, or is it??? No, it isn't currently a full Ada 2012 compiler, but I don't see the relevance of that. This AI wasn't written against Ada 2012 compilers. > Yes, but in the case of GNAT, we would be introducing this "worst > flavor" incompatibility for gnat users who update to Ada 2012, that > would be really horrible, definitely not worth it, and definitely much > more damaging than a theoretical issue with moving between GNAT and as > yet non-existent other Ada 2012 compilers! This isn't a theoretical issue involving non-existent compilers, it's a practical issue involving currently existing compilers. **************************************************************** From: Robert Dewar Sent: Thursday, May 12, 2011 12:37 PM >> But is not currently a full Ada 2012 compiler, or is it??? > > No, it isn't currently a full Ada 2012 compiler, but I don't see the > relevance of that. This AI wasn't written against Ada 2012 compilers. Well the relevance is that we are specifically talking about the Ada 2012 version of GNAT and what we should do for that. But you are right this is a long standing issue, which has been around for a while, which is why we are reluctant to make a non-upwards compatible change given no one has complained. For interest, IS this really more than a theoretical issue? Have you actually had users of your compiler, porting code from GNAT or to GNAT who have bumped into this difference, if so it would be interesting to know more about the exact case. >> Yes, but in the case of GNAT, we would be introducing this "worst >> flavor" incompatibility for gnat users who update to Ada 2012, that >> would be really horrible, definitely not worth it, and definitely >> much more damaging than a theoretical issue with moving between GNAT >> and as yet non-existent other Ada 2012 compilers! > > This isn't a theoretical issue involving non-existent compilers, it's > a practical issue involving currently existing compilers. We are only talking about the GNAT 2012 compiler here, for previous versions of GNAT, this might or might nog be a bug, but it is a bug that has never been reported, so hardly at the top of our implementation priorities! Whenever you have a change that involves major reorganization of critical parts of the compiler, you have to be sure that the change is worth while, that's definitely not the case here, it would be an overall negative to make this change, so it won't happen. After all as you point out this refers to previous bersions **************************************************************** From: Randy Brukardt Sent: Thursday, May 12, 2011 12:51 AM > > But is not currently a full Ada 2012 compiler, or is it??? > > No, it isn't currently a full Ada 2012 compiler, but I don't see the > relevance of that. This AI wasn't written against Ada 2012 compilers. Right. This AI confirms that the language is defined as intended from Ada 95 on. > > Yes, but in the case of GNAT, we would be introducing this "worst > > flavor" incompatibility for gnat users who update to Ada 2012, that > > would be really horrible, definitely not worth it, and definitely > > much more damaging than a theoretical issue with moving between GNAT > > and as yet non-existent other Ada 2012 compilers! This has nothing to do with Ada 2012; the behavior of GNAT is wrong for Ada 95 onwards. Users of any version of the language have a right to expect that the compilers implement the language as specified. Note that this AI changes no ARM wording. Making such a change would be the worst kind of incompatibility vis-a-vis the language. Also note that we explicitly decided not to make an ACATS test in this area; GNAT can ignore this AI if it wants and there will be no consequence (other than Dan's customer's griping). > This isn't a theoretical issue involving non-existent compilers, it's > a practical issue involving currently existing compilers. Like I said, the only consequence is Dan's griping. ;-) I happen to agree with Dan, but I also realize that there is a compatibility cost to changing existing behavior. When we discussed this, we decided that forcing *any* compilers to change was a bad idea. Thus the explicit lack of an ACATS test. **************************************************************** From: Robert Dewar Sent: Thursday, May 12, 2011 12:58 PM > Note that this AI changes no ARM wording. Making such a change would > be the worst kind of incompatibility vis-a-vis the language. > > Also note that we explicitly decided not to make an ACATS test in this > area; GNAT can ignore this AI if it wants and there will be no > consequence (other than Dan's customer's griping). Wouldn't it be better for the RM to just be honest and say that the order is unspecified, this really is not an incompatibility in practice, since Dan or anyone else is free to maintain the old behavior. >> This isn't a theoretical issue involving non-existent compilers, it's >> a practical issue involving currently existing compilers. > > Like I said, the only consequence is Dan's griping. ;-) Yes, I understand, but it would be interesting to know if Dan actually had a customer who ran into this, or whether this is just a theoretical issue. > I happen to agree with Dan, but I also realize that there is a > compatibility cost to changing existing behavior. When we discussed > this, we decided that forcing *any* compilers to change was a bad > idea. Thus the explicit lack of an ACATS test. And then there is the unanticipated discovery that it is entirely impractical to change the behavior of GNAT here, so I am afraid Dan will have to keep on griping. **************************************************************** From: Randy Brukardt Sent: Thursday, May 12, 2011 1:01 PM > I think AI05-0130-1, Order of initialization/finalization of record > extension components, should be reconsidered. > > This AI requires that, in rare cases, a component of an extension part > be initialized after components of the parent part, and, if > controlled, be finalized before components of the parent part. This > is a ramification. It is indeed what the RM says, but I'm pretty sure > that if Tuck and I had noticed this ramification during 9X, we would > have fixed it. > I suspect ARG passed this without thinking through the implementation > difficulties, and user confusions. Did you even read the AI? It specifically says that there might be user confusions and associated bugs, but also that the language rules prevents a different set of bugs. No one could think of a good reason to prefer one set of bugs to another, and changing the language to *introduce* bugs doesn't make much sense. What you might have done in 1993 is irrelevant today; the language has been this way for 16 years and we'd need a critical reason to change it. > I suspect all Ada 2012 compilers do not obey this AI. There are no Ada 2012 compilers (because there is no Ada 2012 yet), so this requirement is trivially met. But since this is also an issue for Ada 95 and Ada 2005, you need to broaden your question to cover those. There is no reason to make this change *only* to an Ada 2012 compiler [I'd argue that is wrong]. Make it to all versions (or none, since there will not be an ACATS test). > This AI is harmful, because: Hard to implement if you have to mix > initialization/finalization of extension components with those of the > parent. > Even harder to implement if you want to be most efficient (i.e. keep > the current mechanism in the 99.9% of cases where it works). > Complicates an already-too-complicated area. > Causes a confusing order for users (programmers expect bottom-up > initialization and top-down finalization). And can cause uninit-var > bugs (better to stick with the bugs we have, than to switch to > different bugs!) -- that is, it's the worst flavor of incompatibility. Only if your compiler is already wrong. Changing the language for no clear reason is the worst form of incompatibility -- it changes runtime behavior with no indication. We agreed long ago that we wanted to minimize such changes. > By the way, note that the issue is not just for controlled types. Any > type can have initializations. Right. Ada 95 wasted a lot of effort trying to define an order of initialization that prevented access to uninitialized objects. This was a total waste of time, because it meant that the order is non-intuitive in many cases, and it doesn't actually fix anything. But it is way too late to fix that mistake. **************************************************************** From: Dan Eilers Sent: Thursday, May 12, 2011 1:05 PM > For interest, IS this really more than a theoretical issue? Have you > actually had users of your compiler, porting code from GNAT or to GNAT > who have bumped into this difference, if so it would be interesting to > know more about the exact case. I believe it was from code Marius Amado Alves wrote to test the Ada 2005 containers packages, related to his Ada-Europe 2004 paper: "A Theory of Persistent Containers and Its Application to Ada". **************************************************************** From: Randy Brukardt Sent: Thursday, May 12, 2011 1:33 PM ... > > This "worst flavor" incompatibility is what currently occurs when > > users switch between compilers. > > True. If I were in charge, I would have required a certain order -- I > don't see any advantage to allowing compiler variations in this area. Umm, you *were* in charge, and you *did* require a certain order!! This order goes back to Ada 95. Maybe it isn't the one you thought you were requiring, but so what? The only real issue here is that the ACATS writers didn't notice it and give us a test early on. Had they done that, this discussion would not be happening. > But it's too late for that now. Perhaps we should allow some > implementation freedom here. For GNAT, it really is a lot of trouble > to "mix" the parent and extension fields. And we don't want subtle > incompatibilities between versions of GNAT, even if that can't be > helped between Eilers' compilers and AdaCore's compilers. But now you work for someone that didn't follow that order, and it now it's a problem. **************************************************************** From: Randy Brukardt Sent: Thursday, May 12, 2011 1:40 PM > > Note that this AI changes no ARM wording. Making such a change would > > be the worst kind of incompatibility vis-a-vis the language. > > > > Also note that we explicitly decided not to make an ACATS test in > > this area; GNAT can ignore this AI if it wants and there will be no > > consequence (other than Dan's customer's griping). > > Wouldn't it be better for the RM to just be honest and say that the > order is unspecified, this really is not an incompatibility in > practice, since Dan or anyone else is free to maintain the old > behavior. Maybe, but it seems like a tough wording problem, not one that I wanted to tackle. You don't want to allow the entire order of initialization to be unspecified, only certain specific cases that cause problems for (at least) one vendor. Also note that adding additional flexibility here also introduces additional possibilities for user bugs. It's not clear that we really want to make it harder to write Ada code. (Practically, of course, it already is harder, but justifying that to WG 9 and the Ada community is a difficult problem. As we've noted on other issues, they don't care that much about your compatibility concerns.) **************************************************************** From: Robert Dewar Sent: Thursday, May 12, 2011 1:42 PM > But now you work for someone that didn't follow that order, and it now > it's a problem. I actually don't know if this is a real problem. As i said to Dan, it would be interested in knowing if he had a real customer run into this (we certainly have not). If not, it is just language lawyers playing with angels on a pin :-) **************************************************************** From: Robert Dewar Sent: Thursday, May 12, 2011 1:45 PM > I believe it was from code Marius Amado Alves wrote to test the Ada > 2005 containers packages, related to his Ada-Europe 2004 paper: > "A Theory of Persistent Containers and Its Application to Ada". OK, so we still don't know if the test was testing this particular feature, in which case to my mind it doesn't count, or whether he had a legitimate coding pattern that ran into this, in which case it would be interesting to see what it was. A legitimate coding pattern running into portability difficulties is always MUCH more convincing than theoretical discussion or purpose-written tests. Personally I would be surprised to see any reasonable code legitimate depending on this order, but that's why it would be educational to discuss the particular example. **************************************************************** From: Robert Dewar Sent: Thursday, May 12, 2011 1:46 PM > But since this is also an issue for Ada 95 and Ada 2005, you need to > broaden your question to cover those. There is no reason to make this > change *only* to an Ada 2012 compiler [I'd argue that is wrong]. Make > it to all versions (or none, since there will not be an ACATS test). Right, and we obviously are not going to "change" all previous versions. **************************************************************** From: Robert Dewar Sent: Thursday, May 12, 2011 1:51 PM > Maybe, but it seems like a tough wording problem, not one that I > wanted to tackle. You don't want to allow the entire order of > initialization to be unspecified, only certain specific cases that > cause problems for (at least) one vendor. Sounds like we should just ignore things and not make any changes > Also note that adding additional flexibility here also introduces > additional possibilities for user bugs. It's not clear that we really > want to make it harder to write Ada code. (Practically, of course, it > already is harder, but justifying that to WG 9 and the Ada community > is a difficult problem. As we've noted on other issues, they don't > care that much about your compatibility concerns.) I am not sure about who the "they" is here that don't care that much about compatibility concerns. The most serious compatibility problems have come from the ARG, not WG9 or the user community (in particular the limited return change). **************************************************************** From: Dan Eilers Sent: Thursday, May 12, 2011 2:04 PM > > I believe it was from code Marius Amado Alves wrote to test the Ada > > 2005 containers packages, related to his Ada-Europe 2004 paper: > > "A Theory of Persistent Containers and Its Application to Ada". > > OK, so we still don't know if the test was testing this particular > feature, in which case to my mind it doesn't count, or whether he had > a legitimate coding pattern that ran into this, in which case it would > be interesting to see what it was. In gnat-examples/containers/shapes/shapes.ads there is type Shape_Type is abstract tagged limited record Control : Control_Type (Shape_Type'Access); --Next : Shape_Class_Access; end record; I think the problem arises in types derived from Shape_Type. **************************************************************** From: Randy Brukardt Sent: Thursday, May 12, 2011 2:14 PM ... > > Also note that adding additional flexibility here also introduces > > additional possibilities for user bugs. It's not clear that we > > really want to make it harder to write Ada code. (Practically, of > > course, it already is harder, but justifying that to WG 9 and the > > Ada community is a difficult problem. As we've noted on other > > issues, they don't care that much about your compatibility > > concerns.) > > I am not sure about who the "they" is here that don't care that much > about compatibility concerns. The most serious compatibility problems > have come from the ARG, not WG9 or the user community (in particular > the limited return change). I was referring to the "some" unreserved keyword silliness. It would be easy to avoid the incompatibility there, but the community won't let us. And this is not the first time, indeed, the reason that we added the limited return change was because the community rejected the original version which used added syntax to preserve the existing semantics. **************************************************************** From: Robert Dewar Sent: Thursday, May 12, 2011 2:22 PM > I was referring to the "some" unreserved keyword silliness. It would > be easy to avoid the incompatibility there, but the community won't > let us. And this is not the first time, indeed, the reason that we > added the limited return change was because the community rejected the > original version which used added syntax to preserve the existing semantics. @start-rant Well I think wrt the limited return a) the ARG underestimated the damage it would do, it has acted as a major barrier to adoption. b) the ARG did not do a good enough job of explaining that damaging scenario to "the community". c) the ARG did not try hard enough to solve this problem without adding extra syntax, e.g. with the use of a pragma. But thats water under the bridge @end-rant Presumably the texinfo command @start-rant should switch to all capitals and an annoying font :-) -) **************************************************************** From: Tucker Taft Sent: Thursday, May 12, 2011 2:40 PM "All Ada 2012 compilers" is a null set at the moment. "All Ada 2005 compilers" might be a more interesting group, in which case you are talking about the Rational compiler and AdaCore. "All Ada 95" compilers seems like the most relevant set at the moment, and for what it is worth, AdaMagic and its descendants (Aonix/Atego and Green Hills) do two passes over all components, regardless of whether they are inherited. I understand that GNAT does all of the inherited components first (with 2 passes), and then does the extension components (with 2 passes). So it does seem to be a potential source of non-portability at the moment. **************************************************************** From: Tucker Taft Sent: Thursday, May 12, 2011 2:52 PM It sounds like we should call it a pathology at this point, in that we promise not to explicitly test for it either way, and let the market decide whether this is a big enough issue to push vendors to conform. I don't think anyone wants to change their compilers at this point in this area. **************************************************************** From: Robert Dewar Sent: Thursday, May 12, 2011 2:55 PM > It sounds like we should call it a pathology at this point, in that we > promise not to explicitly test for it either way, and let the market > decide whether this is a big enough issue to push vendors to conform. > I don't think anyone wants to change their compilers at this point in > this area. I think it's more honest to call it a pathology if we have reason to forbid an ACATS test. Indeed isn't that precisely the mechanism we normally use for forbidding ACATS tests? **************************************************************** From: Bob Duff Sent: Thursday, May 12, 2011 2:56 PM > Did you even read the AI? Yes. I just don't agree with it. **************************************************************** From: Bob Duff Sent: Thursday, May 12, 2011 2:53 PM > ... > > > This "worst flavor" incompatibility is what currently occurs when > > > users switch between compilers. > > > > True. If I were in charge, I would have required a certain order -- > > I don't see any advantage to allowing compiler variations in this > > area. > > Umm, you *were* in charge, and you *did* require a certain order!! Not really. Tucker was in charge, and this was one of the few things we agreed to disagree about. As a general principle, I like to nail down evaluation orders of things. I realize that most of the Ada designers (including both Ichbiah and Tucker) believe the opposite. >...This > order goes back to Ada 95. Maybe it isn't the one you thought you were >requiring, but so what? Right, I thought it only applied within a single record. The case addressed by the AI simply didn't occur to me at the time (9X). >...The only real issue here is that the ACATS writers didn't notice it >and give us a test early on. Had they done that, this discussion would >not be happening. > > > But it's too late for that now. Perhaps we should allow some > > implementation freedom here. For GNAT, it really is a lot of > > trouble to "mix" the parent and extension fields. And we don't want > > subtle incompatibilities between versions of GNAT, even if that > > can't be helped between Eilers' compilers and AdaCore's compilers. > > But now you work for someone that didn't follow that order, and it now > it's a problem. GNAT is obeying what I thought was the Ada 95 rule. It is not obeying the rule that I think is best, nor is it obeying the rule in the RM and the AI. So, no, I haven't changed my mind since joining AdaCore. My main concern in the GNAT case is to avoid stirring around the code in a very delicate area, with the risk of introducing bugs, for a "feature" that seems so marginal. **************************************************************** From: Bob Duff Sent: Thursday, May 12, 2011 3:24 PM > In gnat-examples/containers/shapes/shapes.ads > there is > > type Shape_Type is abstract tagged limited record > Control : Control_Type (Shape_Type'Access); > --Next : Shape_Class_Access; > end record; > > I think the problem arises in types derived from Shape_Type. The problem would arise if Initialize or Finalize of Control_Type were to do dispatching calls to operations of Shape_Type. Or downward type conversions. I don't see any such -- Control is just inserting/deleting pointers to the shapes into/from some container. But you're right that the problem COULD arise given the above type. **************************************************************** From: Dan Eilers Sent: Thursday, May 12, 2011 5:17 PM The initializate/finalize routines do I/O, and I suspect that the ordering of these I/O operations was the issue. I mentioned Marius Amado Alves, but I think now he probably didn't originally write the code involved. ****************************************************************