home *** CD-ROM | disk | FTP | other *** search
- 5-Apr-86 14:51:29-MST,4792;000000000001
- Return-Path: <@USC-ISIF.ARPA:info-ada-request@usc-isif.arpa>
- Received: from USC-ISIF.ARPA by SIMTEL20.ARPA with TCP; Sat 5 Apr 86 14:51:20-MST
- Received: FROM berkeley BY USC-ISIF.ARPA WITH TCP ; 5 Apr 86 13:10:48 PST
- Received: by ucbvax.berkeley.edu (5.48/1.11)
- id AA01699; Sat, 5 Apr 86 12:34:03 PST
- Date: 4 Apr 86 13:36:35 GMT
- From: sftig!sfsup!sfmag!sftor!cw@ucbvax.berkeley.edu (C.S.Wetherell)
- Organization: AT&T Bell Laboratories, Summit N.J.
- Subject: Two characteristic programming errors in Ada
- Message-Id: <951@sftor.UUCP>
- Sender: postmaster@usc-isif.arpa (fix your mailer)
- Real-Annoyed-Sender: usenet@ucbvax.berkeley.edu
- Errors-To: <info-ada-request@usc-isif.arpa>
- To: info-ada@usc-isif.arpa
-
- While porting some programs from the Simtel20 archives to our new
- compiler, I had some difficulty with one of them. Upon investigation,
- I discovered two subtle but characteristic misuses of Ada. I am sure they
- are quite common, so I will protect the author.
-
- Consider the following procedure declaration (ignore its innards for
- the moment)
-
- procedure Does_A_Check(Formal : in out NATURAL);
-
- and the skeletal calling routine
-
- with Does_A_Check;
- procedure Im_A_Caller is
- Actual : NATURAL;
- begin
- Does_A_Check(Actual);
- end;
-
- When this pair was linked and executed, a constraint exception was raised at
- the point of call. [This happened to be particularly mystifying in the
- ported program, because the program was carefully taking care of all
- exceptions and I couldn't tell at first exactly what was causing the
- program to fail. Some embedding of trace statements uncovered the
- difficulty after a bit.] Of course, the reason the constraint error
- was raised was that variable Actual in Im_A_Caller was not
- initialized; there is no requirement that the initial value of
- a variable be within its declared bounds (with exception of access
- types, of course). Since formal in-out parameters are checked
- for constraints at procedure entry, a constraint error was raised.
- I can only assume that the particular program had always been compiled
- and executed on a system where the initial values were within bounds;
- this is, of course, an example of a bug common to other languages as
- well.
-
- However, there is a second bug in the program. Let us now
- consider the body of Does_A_Check:
-
- procedure Does_A_Check(Formal : in out NATURAL) is
- begin
- Formal := 0;
- ...
- Something := ... Formal ...;
- ...
- end;
-
- Notice that the first thing Does_A_Check executes is an initializing
- assignment to Formal; the routine really doesn't care about the
- in-bound value of the actual argument at all. In fact, the only
- reason that Formal is declared "in out" is so that it can be used
- on the right-hand side of some statements. Now, the Ada rule is that
- an "out" parameter cannot be so used; the parameter may have an
- undefined value at some places of such usage and the rules about
- no right-hand usage keep the compiler from having to do a flow
- analysis to determine if a particular usage is after a definition.
- Here, the programmer, to save declaring a local variable, just made
- Formal "in out"; then it can be used on the right. But the cost is
- unexpected constraint errors or extra work for the caller;
- after all, the caller doesn't know (in theory) why the formal parameter
- is "in out" and may have to go to considerable trouble to guarantee that
- the actual argument has an acceptable value; this is disturbing when
- the formal doesn't really need the initial value.
-
- The moral seems to be to use "in out" parameters only when the
- called routine actually needs the initial value; otherwise, use
- a paradigm like
-
- procedure Does_A_Check(Formal : out NATURAL) is
- Local : NATURAL;
- begin
- Local := 0; -- yes, this could be done in the declaration.
- ...
- Something := ... Local ...
- ...
- Formal := Local;
- return;
- end Does_A_Check;
-
- Finally, I might note that this problem was uncovered partly because our
- compiler temporarily is storing characters in 16-bits while a little
- part of our code generator is undergoing additional education about
- the differences between signed and unsigned bytes. One version of the
- problem was using characters instead of NATURAL's. If the Actual
- from above had been an 8-bit character, it might have been automatically
- truncated to within the constraints; as a 16-bit character, it was not.
- There is no guarantee in Ada about the sizes of types beyond the rules
- governing type declarations; this particular stretch of code was
- mildly unrobust in the face of changing sizes
-
- Charles Wetherell
- AT&T Information Systems
- Summit NJ
-