From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,9a586954b11ae008 X-Google-Attributes: gid103376,public From: bobduff@world.std.com (Robert A Duff) Subject: Re: What Happened While I Wasn't Looking? Date: 1997/04/09 Message-ID: X-Deja-AN: 231806421 References: <1997Apr2.202514.1843@nosc.mil> <1997Apr7.182117.22958@nosc.mil> Organization: The World Public Access UNIX, Brookline, MA Newsgroups: comp.lang.ada Date: 1997-04-09T00:00:00+00:00 List-Id: In article <1997Apr7.182117.22958@nosc.mil>, Charles H. Sampson wrote: > My thanks to Bob for his response to my post. I truly appreciate >it. Unfortunately, I don't agree with much of it, so I follow up. Well, at least we both seem to agree that one shouldn't make overlaid variables very much. There's not much difference between "never" and "hardly ever", in practise. > It depends on how you treat erroneousness. I've been surprised at >some of the responses to this thread that seem very close to relishing >the erroneous constructs as potentially nice holes that can be exploited >when necessary. When I taught Ada 83 I pointed out that they have no >language defined semantics, a compiler is not required to detect them >and often can't, and, even if you discover what the semantics are for >your particular combination of compiler and target computer, there's a >very good chance that it's not portable and they might even change in >the next version of the compiler. Conclusion: Avoid them. (By the way, >I know the drill. I'm using "erroneous construct" as a convenient >shorthand for the much longer, technically correct, phrase.) Agreed -- one should avoid things that are erroneous. It helps if it's quite clear what's erroneous, and you can't do it by accident. That's probably the case here -- if you write an Address clause, you know you're doing something questionable, and you can be careful. A much worse case is like in Ada 83, where use of an uninitialized variable is erroneous -- it's easy to do by accident, and it doesn't help to say, "Well, don't do that." > That's at least an arguable point. Carried to its extreme, which >I know is not being advocated here, you get to the point of saying, "Put >anything at all into the language, provided you've included good ver- >sions of all the bad things." Certainly the effort that culminated in >Ada 83 had a lot of "do not allow" guidelines. True, but I think the language designer should concentrate on making sure enough functionality is available in a safe way, so that the evil features aren't needed very often. IMHO, that's a more effective strategy than going around forbidding evil deeds. (Forbidding evil deeds is really hard in chap 13, because it's at the "wrong" level of abstraction -- it's hard to write precise rules that apply to all possible machines, so it's better to let implementers decide, since they have their hands on a particular machine.) > Yes, they can, and they can be non-portable as well. Rephrasing the >point that I tried to make before: The advantage of Unchecked_conversion >is that it is "self-flagging". Every place that it appears in the >source code is a potential trouble spot that has to be investigated when >porting. In the case of overlaying, it's not the overlay itself that >must be investigated, but every reference to the two objects involved. >Probably most of those references will be benign. If you unchecked-convert X'Address to an access type, then the same problem occurs -- you have to track down all uses of that access value. > I don't follow this. You seem to be saying that because an access >value can sometimes (often) be created using Unchecked_conversion, then >it can create aliases. I'll concede that, but it seems to me to be no- >thing more than the general problem of aliasing through pointers. It's worse, because normally, you know that (1) you can't have an access value pointing at X unless X is aliased, and (2) if X is of type T, you only have to worry about access-to-T types. Unchecked_conv breaks these nice properties. > This is off my main subject, but maybe somebody can explain >13.9(15) to me. I find it unusual for a language definition to say, "A >compiler may generate code to implement the semantics of this feature." I don't see how you read it that way -- it's not saying "may generate code to implement". It's saying *should* generate *efficient* code. Yes, I think that should go without saying. The reason 13.9(15) exists is to make some reviewers happy. Those reviewers had been burned by inefficient implementations of unch conv in Ada 83, and wanted to use RM95 as a hammer to beat on implementers. I don't think that's what standards are for, and I didn't really think 13.9(15) was needed. > No, certainly everybody isn't going to do that. There's a large >body of software engineers out there who, like me, look upon Ada as a >gift from the gods. On the other hand, there are a lot of Ada program- >mers, the kind that used to be called hackers, who will try anything to >"get the job done". They might even be anti-Ada. (Let's avoid discus- >sion of the mandate. Such people could be part of the troops on a large >project whose leaders have chosen Ada for reasons that have nothing to >do with the mandate.) If their mindset is such that they don't see any- >thing wrong with overlays, they'll try to use them. True, but those are the same folks who will happily use erroneous things, and will who believe that language semantics is defined by whatever their current compiler happens to do. IMHO, you can't prevent incompetent programmers from writing bad code without crippling the language so far as to be useless. So you shouldn't try. > Wait a minute! The injunction in Ada 83 is against overlaying ob- >jects and program units. 13.3(13) says that the programmer must ensure >that the address given in an address clause is valid. Other than the >appearance of the word _erroneous_, I see no connection between them. >(The term _valid address_ appears to be undefined in the RM--at least >it's not in the index--so I have to guess that it means things like en- >suring word or paragraph alignment when required by the datum.) Right -- the term "valid address" is not defined by the RM. It is entirely up to the implementation which addresses are valid in which circumstances. Word alignment might be part of it, but it could easily be much more. There's some discussion of this in the AARM-13.3: 12.b The validity of a given address depends on the run-time model; thus, in order to use Address clauses correctly, one needs intimate knowledge of the run-time model. 12.g If X is not allocated on a storage element boundary, X'Address points at the first of the storage elements that contains any part of X. This is important for the definition of the Position attribute to be sensible. [Note that the implementation gets to choose how to allocate...] > I'd like to see examples of both of these claims. In particular, >I'd like to know what the "be careful" rules are that are going to avoid >maintenance headaches. Remember, my long experience is just the oppo- >site, that overlaying causes maintenance headaches. I need to be con- >vinced that all of that experience is anomalous. No, your experience is quite correct. As far as encapsulating: If you declare a pair of local objects in a single procedure, 5 lines long, and use address clauses, then it's pretty well encapsulated. If you need the objects to live longer than that, then put them in a package body. I wouldn't normally expect such variables to be globally visible! > You get reluctant o. k. from me on that one. It seems to me to be >very close to lying to the compiler and maintenance programmer again, >although technically it isn't. I think the implication is that aliased >objects will be designated by access values, but nothing in the RM that >I can find says that that is the purpose of aliasing. 13.3(16) makes that connection: 16 X'Address should produce a useful result if X is an object that is aliased or of a by-reference type, or is an entity whose Address has been specified. > I'm impressed. Apparently 13.3(13) can be read to say: If an ad- >dress clause causes a bad effect, then the specified address was invalid >and the program is erroneous. I certainly don't get any comfort out of >such a flexible reading. Well, I think 13.3(13) is pretty broad. It allows the implementation a lot of freedom in declaring things erroneous. On most machines, addresses will behave as you might be used to. But, for example on a Symbolics Lisp machine, pretty much *any* use of addresses will be incorrect. Also, the compiler has some freedom in making the trade-off between agressive optimizations, versus making low-level features work "as expected". - Bob