From bobduff Wed Dec 16 15:56:22 1992 From: bobduff (Bob Duff) To: ada9x-mrt To: iso@ajpo.sei.cmu.edu Subject: LSN-1064 on User-defined Initialization/Finalization/Assignment !topic LSN on User-defined Initialization/Finalization/Assignment !key LSN-1064 on User-defined Initialization/Finalization/Assignment !reference MS-7.4.5;4.6 !reference LSN-1056 on Limited Function Return and User-defined Clone !reference LSN-1059 on Dangling Task Id Checking !from Bob Duff $Date: 92/12/16 15:49:30 $ $Revision: 1.4 $ !discussion This Language Study Note is an update to LSN-1056 on Limited Function Return and User-defined Clone. At the November ISO/WG9 meeting in Salem, the approach of LSN-1056 was tentatively approved (unanimously). Since the idea was so new, the MRT was directed (by resolution number 10-6) to study its impact on the rest of the language, and on implementations. This LSN is in response to that resolution. Our study of the implementation difficulty of the (non-limited) Controlled type produced no surprises. The feature is definitely non-trivial to implement, but, as explained in LSN-1056, that difficulty is somewhat offset by the reduced complexity of limited function return. From a semantic point of view, the language as a whole is simpler without the special limited function return semantics previously proposed. Finally, the small net increase in implementation difficulty buys us a great deal of benefit in terms of usability. We also requested that the implementer halves of the U/I teams study the implementation issues. RR Software studied the issue in detail. No great implementation difficulties were reported. RR Software has stated that they believe the proposal to be a net win. On the subject of limited function return, one glaring error in LSN-1056 should be pointed out: It states that the implementation can easily detect limited function return as a run-time error. This is incorrect. (Thanks to Brian Dobbing for pointing this out.) Consider, for example, a function that returns X.all, where X might point into a user-defined storage pool. The compiler cannot tell which storage pool, in the general case, and storage pools are not required to allocate their storage from any particular place. Therefore, the compiler cannot determine accessibility by inspecting the address of the returned object. Therefore, we have decided to change the rule to this: For a function whose result type is inherently limited, the expression of the return statement must be the name of a global object, a call to a global function, a dereference of an access parameter, or a parenthesized expression, qualified expression, or type conversion of one these things. This detects most of the problems at compile time. In addition, a run-time check is made that the returned object is dynamically accessible from where the function is declared. (The run-time check is needed for access parameters and to avoid contract model problems in generics.) These rules allow the caller of a function with an inherently limited result type to assume that the result will be accessible from where the called function is declared. As stated in the LSN, inherently limited objects are always passed by reference, and returned from functions by reference. The above rules ensure that this is possible without the "lazy stack cutting" of previous proposals. It has the side benefit of turning Ada 83's erroneous (by ARG fiat) local task return into a compile-time error in most cases, and a run-time error in the others. This rule is not quite as simple as was (incorrectly) suggested by LSN-1056. However, it is reasonably simple, and does not require the special semantics of inherently limited functions that had been proposed previously. The reasoning of LSN-1056 still applies: Since Controlled is non-limited, the ability to return local inherently limited values is much less important, so we can live with the above easily-implemented rule for limited function return. The implementation cost then moves to the support for user-defined Clone, which is necessary to make a non-limited Controlled type work properly. We have not discovered any major new semantic interactions between the Clone proposal and other features of the language. The interaction with Volatile, Atomic, and aliased objects is as stated in LSN-1056. The Root_Storage_Pool type, which supports user-defined storage pools, needs to be derived from Limited_Controlled, not from Controlled. (To allow copying of storage pools would wreak havoc; that type definitely wants to be limited!) One issue raised at the Salem meeting was the effect on the efficiency of generic code sharing. As we stated at the meeting: - If the compiler implements universal sharing, then it already needs to pass some sort of thunk for assignment, which knows about copy sizes, and necessary constraint checks. The efficiency of existing actual thunks will not be affected by the possibility of new thunks containing some user-defined code. - If the compiler implements partial sharing, it is already making some decision about which instances are similar enough to share. (For example, if there is a formal integer type, it might create one copy for each different integer size supported by the hardware.) The implementation will probably want to enhance the decision, so that if the actual has a user-defined Clone, a different copy of the code is used than if the actual does not. One other issue that was raised at the Salem meeting is this: Now that we have this fancy new capability, how should it be used in language-defined library units? Our plan is as follows: - We decided not to make type Text_IO.File_Type a non-limited controlled type, due to possible implementation complexity. However, implementations might find it useful to derive it (internally) from Limited_Controlled in order to clean up, as allowed by AI-00546. - The string handling package (which used to be part of the IS Annex, but is being moved to the core, as part of the predefined environment), will not support a true dynamic string data type based on Controlled. This decision is based on schedule concerns; we don't see any compelling reason to have such support, and deciding exactly which operations to support and so on is not easy. Instead, it will continue to support the previously-proposed VString type that can vary in length up to a maximum size. Users can define such packages if they so desire. If we finish everything else early, we can always change our mind. :-) - In the interface-to-C package, there will be a nul-terminated string data type, with suitable conversion operations. We considered basing this on Controlled, in order to ease the heap management. However, we rejected that idea, because the C string data type needs to be at a lower level of abstraction. Its representation needs to match that of C, not that chosen for type Controlled (a tagged type). Users should have full control over storage management for this type. - It has been pointed out that type Task_ID could be a controlled type in order to facilitate checking for dangling Task_ID's. (See also LSN-1059.) This is true. However, it is really an implementation technique, and not a language issue. Therefore, we see no need to mention it in the new RM. Other techniques are also possible, of course. SUMMARY: Our proposal for user-defined assignment, based on a non-limited Controlled type with a primitive Clone operation, stands. We have found no serious problems with it. The limited function return proposal of LSN-1056 was incorrect, and is modified as outlined above. The current proposals on these subjects are not trivial to implement, but neither are they extremely difficult. We believe the cost-benefit tradeoff makes these proposals preferable to any previous ones. Since many users have been clamouring for user-defined assignment for some time, and since user-defined assignment is fully supported by some of our competitor languages, it is a relief to be able to provide it with a semantically clean and simple proposal. ------ Output from automsg.perl ------ Mail received from bobduff *** Key LSN-1064 given to topic 'LSN on User-defined Initialization/Finalization/Assignment' ----------- End of output ------------