Version 1.3 of acs/ac-00011.txt

Unformatted version of acs/ac-00011.txt version 1.3
Other versions for file acs/ac-00011.txt

!standard 4.6 (00)          01-09-13 AC95-00011/01
!class uninteresting 01-09-13
!status received 01-09-11
!subject
!summary
!appendix

!topic Aliased components in Interfaces.C.Strings.chars_ptr_array
!reference RM95-B.3.1(6)
!from Florian Weimer 01-09-08
!discussion

The components of arrays of type chars_ptr_array are not aliased.
This means that the chars_ptr_array type cannot be used in
instantiating the generic package Interfaces.C.Pointers.  The latter
seems to be desirable, because representing a list of strings as
consecutive char * values, terminated by a NULL pointer, seems to be
common idiom in C (for an example, see ISO/IEC 9899:1999, section
5.1.2.2.1).

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

From: Randy Brukardt
Date: Thursday, September 13, 2001, 3:00 PM

I don't think this is worth bothering with. Chars_Ptr_Array is never used in
the package Interfaces.C.Strings, so there is nothing preventing the user
needing a type like from declaring his own. And then they can declare the
components to be aliased (or anything else they need, for that matter).
(Indeed, I see this type as gratuitous junk - we don't fix junk.)

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

From: Robert Duff
Date: Friday, September 14, 2001, 8:47 AM

> (Indeed, I see this type as gratuitous junk - we don't fix junk.)

I'm not sure why it's gratuitous junk.  It reflects a common usage in C,
and this package is supposed to have useful stuff like that.

However, in C every array has aliased components (in the sense that you
can form the address of any component), so it seems like any array that
is of general use, and is intended for interfacing to C should have
aliased components.

It's such an easy fix...

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

From: Robert Dewar
Date: Tuesday, September 18, 2001 3:08 AM

<<However, in C every array has aliased components (in the sense that you
can form the address of any component), so it seems like any array that
is of general use, and is intended for interfacing to C should have
aliased components.>>

Hmmm! interesting, should convention C for an array imply this property?

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

From: Robert Dewar
Date: Tuesday, September 18, 2001 2:57 AM

<<(Indeed, I see this type as gratuitous junk - we don't fix junk.)>>

Yes, we do :-)

For the record, I agree with the very simple and harmless proposal to
make this type have aliased components.

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

From: Randy Brukardt
Date: Friday, September 14, 2001, 2:58 PM

> I'm not sure why it's gratuitous junk.  It reflects a common usage in C,
> and this package is supposed to have useful stuff like that.

I don't think packages should have things in them that user can do as easily
themselves. For the use-adverse, a type like this is actually harder to use
than declaring your own. If the package provided some operations on the type,
then there would be some value, but that is not the case for this type.

> However, in C every array has aliased components (in the sense that you
> can form the address of any component), so it seems like any array that
> is of general use, and is intended for interfacing to C should have
> aliased components.

I don't disagree. I just don't think this type should be in the package in the
first place, and I doubt that there is much use of it, so I don't think we
should be taking the risks of changing it.

> It's such an easy fix...

For implementors, sure. However, making a component aliased can cause the
representation of an array to change. Thus, there is a (small) risk of breaking
existing programs (if they depend in some way on the representation, not
unlikely when interfacing). I would have thought that there are no such
programs, but the existence of this comment means that somebody tried to use
this type (heaven knows why). Persumably there are others who also did so.

I don't think this type deserves introducing an incompatibility, no matter how
small or unlikely.

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

From: Robert Dewar
Date: Tuesday, September 18, 2001 3:11 AM

FUD! It is obvious in this particular case that making the components
aliased will not change the representation in any existing Ada 95
implementation.

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

From: Robert Duff
Date: Saturday, September 15, 2001, 2:12 PM

> If the package provided some operations on the
> type, then there would be some value, but that is not the case for this
> type.

Well, it provides all the usual operations like array indexing...

> For implementors, sure. However, making a component aliased can cause the
> representation of an array to change.

Not in this case -- it's interfacing to C, so we know what it's
representation is.  The components are "really" aliased on the C side,
so the representation has to reflect that.

> I don't think this type deserves introducing an incompatibility, no matter
> how small or unlikely.

Shrug.  I don't think it's worth expending a whole lot of energy arguing
about it.

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

From: Florian Weimer
Date: Sunday, September 16, 2001 4:52 AM

> Not in this case -- it's interfacing to C, so we know what it's
> representation is.  The components are "really" aliased on the C side,
> so the representation has to reflect that.

There doesn't seem to be a requirement in the standard that
chars_ptr_array is C compatible.

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

From: Robert Dewar
Date: Tuesday, September 18, 2001 4:05 AM

OK, but that's really a language lawyer dancing on a pin type argument,
you have to read what's implied in such a case, and of course this
is implied.

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

From: Robert Duff
Date: Tuesday, September 18, 2001, 9:42 AM

In case anyone is curious about where chars_ptr_array came from, I dug
up the following comment.  Interestingly, the suggested instantiation
was not added.

- Bob

================================================================

!topic C interface packages
!reference RM9X-B.3;5.0
!from Robb Nebbe 94-09-07
<<reference as: 94-4697.a Robb Nebbe 94-9-7>>
!discussion

I have been using the C interface packages extensively and a couple of
possible improvements have come up during my work. I believe them
to be quite minor in scope (there are almost no semantics to define)
but nonetheless useful.


1) It would be nice to add a function in package Interfaces.C

function Is_Nul_Terminated (Item : in char_array) return Boolean;

I have places in my code where I already have a char_array
object (so I'm not converting from a String where there is
an parameter Append_Nul) and need to check if it is Nul
terminated (it is actually a precondition for a subprogram and
me raising an exception is a lot better than a segmentation fault)
In many cases I already know if a particular char_array is Nul
terminated or not but every once in a while I find myself
needing to check.


2) The addition of the type chars_ptr_array in Interfaces.C.Strings
and a preinstantiation of Interfaces.C.Pointers would be useful.


type chars_ptr_array is array (size_t range <>) of chars_ptr;

- and -

with Interfaces.C.Strings; use Interfaces.C.Strings;

package Interfaces.C.String_Lists is  -- or some other name.
  new Interfaces.C.Pointers( Index         => size_t,
                             Element       => chars_ptr
                             Element_Array => chars_ptr_array,
                             Terminator    => null_ptr );


The use of char **foo or char *foo[] is fairly common in C; common
enough that a preinstantiation of Interfaces.C.Pointers should
probably be included in B.3. Even if a preinstantiation is not provided
it should be made fairly simple to instantiate Interfaces.C.Pointers
for this common case. Right now chars_ptr_array is the missing piece
and I can't think of any good reasons to why it shouldn't be declared
in Interfaces.C.Strings.

In order to limit any confusion it might be a good idea to rename
char_array_ptr (a general access type to char_array found in
Interfaces.C.Strings) to char_array_access.

- Robb Nebbe

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

From: Pascal Leroy
Date: Tuesday, September 18, 2001, 10:37 AM

> package Interfaces.C.String_Lists is  -- or some other name.
>   new Interfaces.C.Pointers( Index         => size_t,
>                              Element       => chars_ptr
>                              Element_Array => chars_ptr_array,
>                              Terminator    => null_ptr );

This instantiation got me thinking on a totally unrelated issue.

The formal array type Element_Array has aliased components, chars_ptr_array
doesn't (in the language as it stands today).

In TC1, we have a rule (4.6(12.1/1)) which forbids view conversions between
array types if one array has aliased components and the other doesn't.  But it
seems to me that we should also have a similar rule for actual/formal matching
in generic instantiations.  Otherwise, it is possible to use a generic to
circumvent 4.6(12.1/1).

Or am I missing something?

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

From: Randy Brukardt
Date: Tuesday, September 18, 2001, 11:44 AM

> In TC1, we have a rule (4.6(12.1/1)) which forbids view conversions between
> array types if one array has aliased components and the other doesn't.  But it
> seems to me that we should also have a similar rule for actual/formal matching
> in generic instantiations.  Otherwise, it is possible to use a generic to
> circumvent 4.6(12.1/1).

Well, we already have 12.5.3(8): "If the formal type has aliased components,
then so shall the actual."

But it appears that an formal type with unaliased components could match an
actual type with aliased components, thus not only circumventing 4.6(12.1/1),
but actually requiring the wrong behavior.

The question is whether changing 12.5.3(8) to require matching of the aliased
component property is an unacceptible incompatibility. (If so, we could define
a "run-time" check that would always be detected at compile-time for
non-sharing implementations.)

> Or am I missing something?

I don't think so.

Note that 12.5.3(8) makes it impossible to instantate Interfaces.C.Pointers
with Chars_Ptr_Array. So it doesn't work for the use described in the comment.

(I must say that I don't find the comment very convincing. The point of the
standard packages is to provide building-blocks that a user couldn't easily
program themselves - for instance, Interfaces.C.Short because its not obvious
what the representation of the C type is, Interface.C.To_C because its not
certain that the representation of C and Ada strings are the same, etc. In a
case like this where there is no barrier to programming the type themselves, it
simply clutters the package. I know that I never go looking in the predefined
packages to see if there is a type that might help; I only do so when there is
a solid reason for doing so.)

Anyway, I take it that at least two ARG members here are calling for an AI??

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

From: Pascal Leroy
Date: Wednesday, September 19, 2001, 4:12 AM

I am certainly calling for an AI to fix the actual/formal matching rule, as it
is clearly a hole in the language.

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

From: Pascal Leroy
Date: Wednesday, September 19, 2001, 4:07 AM

> Hmmm! interesting, should convention C for an array imply this property?

No, I disagree, representation items should not affect the static semantics of a
type.  Otherwise you run into the situation where the legality of a construct
may depend on a Convention pragma appearing after that construct.  For instance:

    type Acc is access constant Interfaces.C.Int;
    type A is array (1 .. 10) of Interfaces.C.Int;
    function F return A;
    procedure P (X : Acc := F (1)'Access); -- Legal?
    pragma Convention (C, A);

With your proposal it would be impossible to check the legality of the 'Access
attribute at the place where it occurs, because type A is not frozen at this
place, and the Convention pragma would later make the components aliased.  To me
that's a no-no: I believe in one-pass semantic analysis.

This being said I'm in favor of making the components of Char_Ptr_Array aliased.
This seems to be a simple, harmless change.

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

From: Tucker Taft
Date: Wednesday, September 19, 2001, 9:10 AM

I could see requiring that the *user* specify aliased for the
array if they plan to also specify convention C, but that seems
a bit onerous.

> ...
> This being said I'm in favor of making the components of Char_Ptr_Array
> aliased. This seems to be a simple, harmless change.

I agree.  Sounds like a "clarification" to me ;-).

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

From: Ted Baker
Date: Wednesday, September 19, 2001, 6:25 AM

I've run into the problem of needing to alias components when doing
C interfacing (Florist).  It would be convenient if convention C
for an array would imply aliased.  However, I guess that would not
solve the basic problem with the pointer-to-array types that are
defined in the standard C interface packages, or would it?

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

From: Pascal Leroy
Date: Wednesday, September 19, 2001, 1:35 PM

> I could see requiring that the *user* specify aliased for the
> array if they plan to also specify convention C, but that seems
> a bit onerous.

But then maybe the user doesn't want aliased components at all, e.g. because
she is not creating pointers to elements of the array, or only does that on
the C side.

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

From: Florian Weimer
Date: Wednesday, September 19, 2001, 2:46 PM

Ted Baker <baker@dad.cs.fsu.edu> writes:

> I've run into the problem of needing to alias components when doing
> C interfacing (Florist).  It would be convenient if convention C
> for an array would imply aliased.

And for a record type, too?  Doesn't this cause problems when
referring to C bit fields?  (I don't use C bit fields, I don't know if
there's a portable way to interface to them from Ada.)

> However, I guess that would not solve the basic problem with the
> pointer-to-array types that are defined in the standard C interface
> packages, or would it?

For Interfaces.C, all types are required to be 'C-compatible',
cf. B.3(42).  I don't think this requirement extends to
Interfaces.C.Strings.  In addition, all array types in Interfaces.C
explicitly have aliased components.

Anyway, it is extremely unlikely that the aliased and unaliased
representations of chars_ptr_array differ in an existing Ada
implementation.  It is hard to image how one can store pointers in an
array in a way which you cannot address the pointers individually.

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

From: Robert Dewar
Date: Wednesday, September 19, 2001, 12:32 PM

<< No, I disagree, representation items should not affect the static
semantics of a type...>>

Representation items OFTEN affect the static semantics of a type, e.g.
pragma Packed means that no more derived subprograms can be given, and
a SMALL clause for fixed-point can affect the value of static expressions.

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


Questions? Ask the ACAA Technical Agent