From: figueroa@CS.NYU.EDU (Samuel A. Figueroa)
Subject: Message from Dewar re: Address Clauses
Organization: New York University
Date: Mon, 31 Aug 1992 16:26:36 GMT

Date: Mon, 31 Aug 92 07:13:31 -0400
From: dewar (Robert Dewar)
Message-Id: <9208311113.AA21505@cs.NYU.EDU>
Subject: Could you forward this to Comp.Lang.Ada

Andrew Dunstan writes:
 "Thanks for pointing this [the rule in 13.5(8)] out - I did actually look
  in the LRM before I posted, but obviously not hard enough! Finding these
  little things in the LRM is like looking for a needle in a haystack."

Well the RM takes many knocks, some deserved, but really! this is somewhat
unfair. If I was wondering about the use of an address clause in Ada, I
should think I would read section 13.5 of the reference manual, whose
title is, reasonably helpfully "Address Clauses". Since this section is
quite short (only 21 lines long plus a short example and a note), it would
seem quite reasonable to read the full 21 lines. 3 of these lines (a
separate paragraph, para (5), contain the restriction stated pretty clearly:

  "Address clauses should not be used to achieve overlays of objects or
   overlays of program units. Nor should a given interrupt be linked to more 
   than one entry. Any program using address clauses to achieve such an 
   effect is erroneous."

So, clear enough. But perhaps it is worth taking a moment to discuss WHY
this restriction is present. There are really two cases. First, the case
where the address clause is used to give two names of exactly the same type
to the same object, something like:

	A : Integer;
	B : Integer;
	for B use at A'Address;

Now of course one might ask what on earth this is good for (if the intent is
simply to give two names to the same thing, please use RENAME!) but on the
other hand, one could take the attitude: sure it's not much use, but why
shouldn't it work? This is one of those interesting cases where the rationale
is not immediately obvious. The trouble is that the expression in the address
clause is not required to be static (quite useful in mapping objects to places
not known till execution time). This means we can have:

	A : Integer;
	B : Integer;
	for B use at Complex_Function (A'Address, ... );

Now the compiler has no way of knowing if a reference to B, or worse still,
a reference to a function which can see B, does horrible things to arbitrary
local variables. Essentially we have provided a critical leak to the 
otherwise firm principle that specifically declared variables are never
implicitly aliased. This would complicate optimizers, and reduce their
effectiveness for no apparent significant functional gain.

[Side note: in Ada/9X, as proposed, we can take the address of a declared
 variable, but the variable must be specifically marked, using ALIASED, to
 warn the compiler optimizer that this kind of aliasing may occur. Presumably
 we could allow the above declarations in Ada/9X if A were marked aliased, but
 it hardly seems worth the effort!]

Back to the restriction, and the more significant application, which is to
get the effect of REDEFINES in COBOL or EQUIVALENCE in FORTRAN. It is clear
that such usage is bound in general to have an implementation dependent
effect. Even in the apparently harmless case involving a variable and 
a constant of the same type, an implementation may store constants and
variables in different formats, different memory hierarchies etc. [someone
already pointed out the ROM possibility].

Now when it comes to language constructs that are said to be implementation
dependent, the RM divides them up into three categories:

  Implementation dependent, documentation in appendix F required
  Implementation dependent, documentation not required
  Erroneous

>From a legalistic point of view, the last two possibilities are exactly the
same, since they both give the implementation total freedom to do whatever
it wants, without telling you what it is doing. On the other hand, the
distinction is significant, because it expresses a point of view. ID is
respectable, it makes your program implementation dependent, and thus
potentially non-portable, but not immoral. Erroneous on the other hand,
expresses the point of view that you really shouldn't be doing this, and
advises implementors that it would be in poor taste to document what they
do in erroneous situations and encourage programmers to make use of the
information.

So, what do you think about the choice in the case of address clauses used
for overlay? Well I think the RM probably made the right choice -- this
really isn't the sort of programming style that fits the Ada mold?

One final note, back to the original problem. The best general solution is
to use access STRING for these kind of situations. Actually access STRING
is a pretty reasonable type for the manipulation of variable length strings.
Of course it means using the heap which you might want to avoid, but in that
case, worry a little about using unconstrained returned values from functions
at all -- many, but not all, implementations secretly use the heap anyway
for this situation. So if you are writing portable code which wants to avoid
using the heap, better to use an interface like GET_LINE, even if it is
clunkier!

	Robert B. K. Dewar (that's quite enough signature for me, thanks!)
Newsgroups: comp.lang.ada