Version 1.1 of acs/ac-00189.txt

Unformatted version of acs/ac-00189.txt version 1.1
Other versions for file acs/ac-00189.txt

!standard B.1          10-02-13 AC95-00189/01
!class confirmation 10-02-13
!status received no action 10-02-13
!status received 10-01-14
!subject Import pragma on dynamically-sized array
!summary
!appendix

From: Adam Beneschan
Sent: Thursday, January 14, 2010  3:55 PM

I'd like some expert opinions about what the Ada language says about this
situation, if anything.

Suppose a subprogram has a local object that is an array whose bounds are not
known at compile time:

   procedure Proc1 (X : String) is
      type X_Bytes is array (X'Range) of Interfaces.Unsigned_8;
      XB : X_Bytes;
   begin
      ...
   end Proc1;

Some implementations will implement this by moving the stack pointer to make
room for XB.  But that may not be appropriate for all execution environments, so
there could be implementations that allocate the data for XB in some other area
of memory, and then XB is maintained (on the stack or in a register) as a
pointer to that memory.  Let's say this latter implementation is being used.

Now someone writes this:

   procedure Proc2 (X : String) is
      type X_Bytes is array (X'Range) of Interfaces.Unsigned_8;
      XB : X_Bytes;
      pragma Import (Ada, XB, "external_symbol");
   begin
      ...
   end Proc2;

Keeping in mind that the convention of XB is Ada (not C or anything other
language), which of the following do you think is closest to the truth?

(1) The language says, implies, or suggests (e.g. in Implementation
    Advice) that the data at the location "external_symbol" will be an
    array of bytes.  That is, it isn't a pointer even though XB would
    be implemented as a pointer without the Import.

(2) The data at the location "external_symbol" will be an array of
    bytes, not because the language says anything about it, but
    because it's the only useful way to do it and everyone would
    assume that it's done that way.

(3) The data at the location "external_symbol" must be a pointer to an
    array of bytes, because the Ada convention in the Import pragma
    requires that the data at location "external_symbol" follow Ada
    conventions for the implementation, which in this case means being
    stored as a pointer because that's the way the Ada compiler would
    do it without the Import.

(4) You can't count on the compiler to treat the data at
    "external_symbol" one way or the other, and it's an error to write
    this kind of code if the program is to be portable.

Thank, I appreciate your thoughts on this.

****************************************************************

From: Randy Brukardt
Date: Thursday, January 14, 2010  8:42 PM

None of these make any sense. The use of pragma Import can have no impact on
whatever is at "external_symbol" -- it is whatever it is. You really need to be
asking what form the data at "external_symbol" needs to be in in order for the
compiler to use it with this Import pragma.

My answer would be that if the data at "external_symbol" is in fact created by
the same Ada compiler and exported with an appropriate Export pragma, it has to
work properly. That is, the representation has to be the same on both sides. And
otherwise what it does is implementation-defined. Which means no one has any
reason to assume anything about the expected representation, nor expect any sort
of portability from compiler-to-compiler.

Note that B.1(38.1/2) makes it the programmers responsibility that the semantics
of interfacing pragmas is correct. This applies just as much to convention Ada
as to any other convention.

Indeed, I really don't see anything that even requires Export to Import to work,
although it would seem nasty if it did not. (But note that it is possible that
exceptions can't propagate through C or Fortran interfacing, to take one
example. So even matching pragmas are not a guarantee.)

Janus/Ada generates code similar to what you are describing here, but I suspect
that the Import/Export pair actually exports the array of bytes. I think it
shares the implementation with address clauses, which would do that. But I
cannot be certain without a lot of research. Indeed, Janus/Ada does this sort of
thing for lots of kinds of objects: ones with address clauses, renames, pragma
Import and Export, dynamically sized objects. In most of those cases (and maybe
all of them), the use of the pointer is treated as an implementation artifact
and is hidden from the user in all ways (including things like
Unchecked_Conversion and streaming). So we wouldn't necessarily say that the
object is "implemented as a pointer".

User expectations are another matter altogether. What's most useful is probably
some version of what you describe as (2). So implementations probably ought to
use (2) as the external model (there is no reason to assume or expect that the
internal and external representations of objects are the same: they almost never
are in Janus/Ada's code shared generics, for instance). But what makes sense for
user has nothing to do with the language definition.

Summary: the language requires nothing. Users might expect (2), and it's always
a good idea to give users what they expect within reason, but that has nothing
to do with this group.

****************************************************************

From: Adam Beneschan
Date: Friday, January 15, 2010  10:59 AM

> None of these make any sense. The use of pragma Import can have no
> impact on whatever is at "external_symbol" -- it is whatever it is.
> You really need to be asking what form the data at "external_symbol"
> needs to be in in order for the compiler to use it with this Import pragma.

Poor wording on my part.  What I meant was, what kind of data should the
compiler assume is at "external_symbol" when compiling the above code.  But I
think you figured that out.

...
> Summary: the language requires nothing. Users might expect (2), and
> it's always a good idea to give users what they expect within reason,
> but that has nothing to do with this group.

Except that many of the people on this group are users and/or understand what
users want, so I thought your opinions from experience would be valuable.  But
my main interest was in finding out, from those who have worked on designing the
language, whether the language had anything to say about this.

Thanks, Randy, for the detailed response---it's definitely helpful.

****************************************************************

From: Bob Duff
Date: Friday, January 15, 2010  11:48 AM

> But what makes sense for user has nothing to do with the language
> definition.

I think I'll frame this quote and hang it on the wall!  ;-)

****************************************************************


Questions? Ask the ACAA Technical Agent