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=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!gandalf.srv.welterde.de!news.jacob-sparre.dk!loke.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Uninitialized out parameters. Date: Wed, 6 Apr 2016 16:30:01 -0500 Organization: JSA Research & Innovation Message-ID: References: <3be79ab3-ebc7-4169-9713-d50349662403@googlegroups.com> NNTP-Posting-Host: rrsoftware.com X-Trace: loke.gir.dk 1459978202 1805 24.196.82.226 (6 Apr 2016 21:30:02 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Wed, 6 Apr 2016 21:30:02 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 X-RFC2646: Format=Flowed; Original Xref: news.eternal-september.org comp.lang.ada:30026 Date: 2016-04-06T16:30:01-05:00 List-Id: wrote in message news:alpine.DEB.2.20.1604062240350.29458@debian... On Wed, 6 Apr 2016, ahlan@marriott.org wrote: >> In the annotated RM, in the section concerning Null Procedures, it says >> "There are no null functions because the return value has to be >> constructed somehow; a function that always raises Program_Error doesn't >> seem very useful or worth the complication" If there are no null >> functions because a return value has to be constructed then surely the >> same applies to null procedures that have out parameters. These too >> should be prohibited [...] > >This seems to be right. It does not make much sense to allow the >declaration of > > procedure X(Formal: out T) is null; > >while prohibiting the declaration of > > function Y return R is null; Playing Devil's Advocate here, the latter always raises Program_Error; if you really meant that there are better ways (see below). The former does nothing at all other than deinitialize its actual parameter. So they're not really the same thing. > The point is, you can neither call X nor Y. Semantically, both statements > > X(Actual); > Actual := Y; > >are equally useless, or at least their effect is equally undefined. No, both are very well-defined. And there is nothing wrong in either case with making a call (so long as Actual is not used afterwards. I have *lots* of procedures for which one or more actuals are meaningless after the call, and better not be touched. (The case where *all* parameters are like that is of course pathological, but to have one of of several is pretty common.) >Allowing the declaration of X, but prohibiting the declaration of Y is >inconsistent. Maybe, but there is a big difference: allowing the declaration of Y is new feature that would be a lot of work for implementers and is 100% useless. (Again, there is a better way to write a function that always raises Program_Error, see below.) Whereas *disallowing* the declaration of X would be additional work for implementers (and now would also be incompatible). The null procedure feature itself has many obvious uses, and you are talking about a tiny corner case. I can see that it might have made sense to disallow out parameters when the feature was defined, but I don't think we ever thought of it. As I noted in another message, a null procedure is semantically just a short-hand for "begin null; end;" and I don't think we considered having *different* Legality Rules for it. And it's definitely too late now; breaking existing code (especially interface declarations) for this issue seems like a non-starter. Such a rule would do very little to reduce this problem (it happens to me periodically for normal procedures), so the incompatibility would just not be tolerable. And of course, changing the rules to raise Program_Error, as the OP suggested, would be even more of a nonstarter as a runtime incompatibility. No one would want programs that work fine today start raising Program_Error because some object that is never used got de-initialized. We had a similar case that involved a real semantic problem with access types, and we eventually decided to make it illegal (rather than raise Program_Error or make it erroneous) as the best of a bad set of choices (Program_Error was the least liked of all). [We did choose Program_Error for a similar case, but that was because we assumed that there were no such programs as "scalar with Default_Value" was first added in Ada 2012, not so for things in Ada 83 (or Ada 2005).] Ada 83 got the handling of uninitialized objects wrong (including this case of out parameters) for a language which defaults to "safe". We're pretty much stuck with that today, changes would break almost all existing code. That's too bad, but I guess it just shows that no language is perfect. >If people really think they need to declare something like the above >procedure X, a revised Ada standard could allow declarations such as > > procedure X(Formal: T) is raise; > >and > > function Y return T is raise; > >where "is raise" stands for "raise Program_Error". That may sometimes come >handy in the context of inheritance, or so. (1) The above null procedure X does not and would never raise Program_Error, so the first part of this doesn't make any sense. (2) The latter can be written in current Ada 2012: (that is, with TC1 implemented) function Y return T is (raise Program_Error); which is both clearer and hardly any longer. I can't imagine why we'd add another feature just to save two parens and a name (that it actually helps to make explicit). Randy.