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/20 Message-ID: <31A087D9.752E@lmtas.lmco.com> X-Deja-AN: 155808824 references: <9605151401.AA04364@most> <319B286E.3B2E@lmtas.lmco.com> <4nh3n7$55g@goanna.cs.rmit.EDU.AU> <319C52B2.36F6@lmtas.lmco.com> <4nppd5$61@goanna.cs.rmit.EDU.AU> 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-20T00:00:00+00:00 List-Id: Richard A. O'Keefe wrote: > > I am a bear of very little brain. > I have worked with _lots_ of languages, and continue to use several. > The policy I described (initialise constants in declarations, initialise > variables as close as reasonable to first use) is one that > - makes sense in _every_ language I use > - makes sense _whatever_ the data type of a variable is. > > If we take "abstract data types" and "uniform reference" at all > seriously, and in Ada I thought we were supposed to, I _should_ be > using a convention for initialisation which doesn't force me to > rewrite the code if I switch from array indices to pointers or vice versa. Two comments: (1) If you really use an ADT for a pointer, you don't have to rewrite anything other than the implementation of the ADT to switch between array indices and pointers. (I showed an example of such an ADT in an earlier thread.) (2) It seems to me that your approach prohibits certain behavior within an ADT. In particular, if you want to assure that any object declared with the ADT has an initial value, it seems like your coding convention would not allow this. As a result, you must depend upon the user of the ADT to consistently provide an initial value on the declaration. If they forget, the assumptions of the ADT may be broken, or the program may behave erroneously. I would think this would weaken, not strengthen, the use of an ADT. It also seems to violate the Ada concept of not explicitly copying information that can be defined in one place. > Somebody reading my code (probably me) shouldn't have to look up the > type declaration (which may be in some other package entirely) to find > out that what _looks_ like an uninitialised variable is actually ok. Wouldn't they have to look up the type declaration (or the ADT declaration, or the algorithm declaration) to determine other information, such as whether the initial value that _was_ provided was OK, in any case? > >Furthermore, what about cases like: > > >(1) type Some_Thingy_Type is record > > Some_Component : Integer := 0; > > end record; > > > Foo : Some_Thingy_Type; -- or should I explicitly initialize it? > > The rule I use is type independent. It's not the ":= 0" in the > type declaration I mind; it's that I don't like relying on it, not > because the compiler will get it wrong, but because I will. However, if all Some_Thingy_Types are supposed to be initially zero (as opposed to "initialized to some integer value"), isn't it more likely that the coder will "get it wrong" if the initialization has to be physically repeated for each declaration? > I actually prefer > > type Some_Thingy_Type is record > Some_Component: Integer; > end record; > > Default_Thingy_Type: constant Some_Thingy_Type := > (Some_Component => 0); > > Foo: Some_Thingy_Type; > begin > ... > Foo := Default_Thingy_Type; I think this may be OK for one Some_Thingy_Type; I wonder about its utility for multiple Some_Thingy_Type objects that are all supposed to have the same (or a related; e.g. sequentially increasing) initial value. > If there is a "normal" initial value for a type, I WANT A NAME FOR THAT VALUE! I don't see any problem with exporting the default value by name from an ADT, for example, to use it in a comparison statement. However, you can have a name without explicitly requiring its use on all declarations. For example: package Doctor is type Object is ...; type Reference is private; -- has initial value of Illegal_Reference. function Illegal_Reference return Reference; ... private type Reference is access Object; -- can change to an integer if desired -- causes all References to be null. end Doctor; package body Doctor is function Illegal_Reference return Reference is begin return null; end; -- returns some integer value if Reference changed. end Doctor; This ADT could still be used with your coding style, as follows: Some_Doctor : Doctor.Reference := Illegal_Reference; However, the initial value would be unnecessary. Note that the ADT assumptions would still be valid if you left the initial value off. However, anyone reading your code who was not familiar with your coding convention would be confused, either (a) because you were double-initializing Some_Doctor and/or (b) because some Doctors were initialized, others weren't. > What I want is static checkers (at _least_ as good as Lint or GCC checking > for uninitialised variables, ideally a lot better because they are pretty > weak) AND DYNAMIC CHECKERS. Yes, this is the old idea of a "checkout > compiler" as opposed to an "optimising compiler". Yes, this is the kind > of thing CodeCenter buys you for C. It has been a while since I used > CodeCenter, but I remember vividly how very efficient a _debugging_ tool > it was. Code didn't _run_ fast, but it certainly _found mistakes_ fast. > > And of course I want them free, yesterday. Well, except for the "free" part, there are certainly analysis tools of this type available for Ada. Some of them might be discounted (if not free) for academia; I don't know. > -- > Fifty years of programming language research, and we end up with C++ ??? > Richard A. O'Keefe; http://www.cs.rmit.edu.au/~ok; RMIT Comp.Sci. -- LMTAS - "Our Brand Means Quality"