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,7dd9b82cd363f55b X-Google-Attributes: gid103376,public From: Ken Garlington Subject: Re: Coding Standards Date: 1996/05/16 Message-ID: <319B286E.3B2E@lmtas.lmco.com> X-Deja-AN: 155166557 references: <9605151401.AA04364@most> content-type: text/plain; charset=us-ascii organization: Lockheed Martin Tactical Aircraft Systems mime-version: 1.0 newsgroups: comp.lang.ada x-mailer: Mozilla 2.01 (Macintosh; I; 68K) Date: 1996-05-16T00:00:00+00:00 List-Id: W. Wesley Groleau (Wes) wrote: > > If you haven't been following a recent "wordy" but interesting thread > in comp.lang.ada... "Wordy," eh? (Everybody has to be a critic.... :) OK, let me take a crack at summarizing the thread, then. The topic is on coding standards for objects (including record components, etc.) which reference other objects. I'm going to call them "pointers," rather than the Ada term "access," for reasons that will hopefully become obvious later. Here's some possible goals for such a standard, and some diverging opinions on how to meet those goals. A. When an Ada access type is being used for a pointer, it would be useful to communicate to the maintainer when the default "null" is a useful value for that object, as opposed to being basically an "undefined" or "uninitialized" value. APPROACH #1: When null is a useful value for a pointer, explicitly initialize the pointer to null, as in: Thingy : Some_Access_Type := null; If the maintainer is aware of the coding convention being used, and assuming that all operations that use this value all work the same way, and that the maintainer looks at the data structure before passing it to the operation, then it would be legal to use this object in an algorithm without checking for null first; e.g. Do_Something ( With_This => Thingy ); If the explicit null is not given, then some code such as the following might be needed: if Thingy = null then -- set the thingy, raise an error, etc. else Do_Something ( With_This => Thingy ); end if; Note that a variation of this approach would declare a value for each appropriate access type; e.g. type Some_Access_Type is access ...; No_Particular_Value : constant Some_Access_Type := null; -- indicates "legal" null ... Thingy : Some_Access_Type := No_Particular_Value; This variation could make it more clear that the original programmer meant to initialize the value for some reason other than ignorance about Ada's default value of null for accesses, particularly if No_Particular_Value is commented. APPROACH #2: Document each operation's assumptions separately at the point where the operation is declared; e.g. procedure Do_Something ( With_This : Some_Access_Type ); -- cannot be null If the maintainer looks at the operation declaration before using it, then the same effect as approach #1 should occur. Note that access to the coding standard is not required to read the code. B. Write code such that it is easy to change the implementation of a particular pointer type from an Ada access type to some other type (e.g., an integer index into a predefined array). [As a side issue, it could be argued that this is a design standard issue, not a coding standard issue.] APPROACH #1. Same as approach #1 for (a) above. Having the explicit initialization permits the maintainer to find those cases where the (now integer) pointer needs to be explicitly initialized, assuming the maintainer has access to the coding standard, etc. APPROACH #2: Create an abstract data type for Pointers (or a particular type of Pointer). By hiding the implementation of the Pointer, it can be changed from an access type to an integer, etc. without any changes of the use of Pointer. Of course, the ADT should reproduce the operations needed by the program (including default initialization of Pointers, and/or the exporting of a No_Particular... value.) The ADT could (and also probably should) explicitly document its purpose, so that the maintainer understands why an access type was not used directly. Note that, even without the comments, access to the coding standards should not be needed to read the code. Note also that, if the Pointer is a generic, it could lead to fewer source lines of code required than the type-declaration plus constant-declaration required in the approach #1 variant. C. Permit the code to check, for each access to a particular pointer, whether the value of the Pointer is No_Particular... or an "uninitialized" value, and to take some action if the value is "uninitialized". APPROACH #1. Same as approach #1 for (a) and (b) above. However, since "null" is used to mean _both_ values in this approach, this will not work. By default, Ada will check for any attempts to deference a pointer initialized to null, so there is some coverage in this area by default. APPROACH #2: Extend the Pointer ADT described in approach #2 of (b) above. The ADT could have each pointer contain a default value (probably null, when the pointer is implemented as an access type) and also export a _different_ No_Paticular... value (in the case of an access type, some allocated value that is not used; in the case of an integer, some value that is in range for the integer type, but not a value which can reference an allocated object). This would allow reliable checking on _any_ access of the pointer, or it could be limited to _dereferences_ of the pointer (as with Ada's Access_Check). Note that it would be fairly easy to turn such checking on and off (or modify it), since it would be encapsulated within the ADT. There was also some discussion about how to detect uninitialized values beyond the Pointer class, which I won't summarize here. -- LMTAS - "Our Brand Means Quality"