An implementation which supports interfacing to C shall support pragma
Convention with a C_Pass_By_Copy identifier. An 'in' parameter of a
C_Pass_By_Copy-compatible type T should be passed as a t argument to a C
function, where t is the C struct corresponding to type T.

!question

B.3(69) says:

Implementation Advice
...
69 An Ada parameter of a record type T, of any mode, is passed as a

t* argument to a C function, where t is the C struct
corresponding to the Ada type T.

The problem with this is that if one has a C function that is passed a
struct, then how can one pass an Ada record to that? One might think that if
the Ada record is passed as an 'in' parameter, it will work. However, the
above Implementation Advice implies that such an 'in' parameter will
correspond to a t* on the C side, rather than a t.

!recommendation

The Implementation Advice in B.3(69) is left unchanged (that is, C-compatible
records are passed by reference).

The convention C_Pass_By_Copy is added to the facilities available for
interfacing with C. This convention can only be used in pragma Convention
(not in pragmas Import or Export) and only when this pragma is applied to a
type.

There is no language interface package corresponding to C_Pass_By_Copy. In
other words, B.1(13) never applies to convention C_Pass_By_Copy, and there is
no package named Interfaces.C_Pass_By_Copy.

A type T is eligible for convention C_Pass_By_Copy if T is a record type that
has no discriminants and that only has components with statically constrained
subtypes, and each component is C-compatible. (The eligibility rules
in B.1(13-18) do not apply to convention C_Pass_By_Copy.)

If a type is C_Pass_By_Copy-compatible then it is also C-compatible.

An implementation supporting interfacing to C shall support pragma Convention
with a C_Pass_By_Copy convention_identifier for a C_Pass_By_Copy-eligible
type.

The following sentence is added to the Implementation Advice in B.3(64-71):

An Ada parameter of a C_Pass_By_Copy-compatible (record) type T, of mode in,
should be passed as a t argument to a C function, where t is the C struct
corresponding to the Ada type T.

Note that the rules B.1(19) and B.1(20) apply to convention C_Pass_By_Copy.
In particular, an implementation may permit other types as C_Pass_By_Copy-
compatible types (e.g., discriminated records).

!wording

(See recommendation.)

!discussion

It was a mistake to require pass-by-reference for records passed to C
functions. However, at this point, it would be disruptive to change the
rule, and there is an alternative (see below).

The most important use of this interface is to take an existing C interface,
and use it from Ada code (as opposed to taking an existing Ada interface, and
mapping it to some corresponding C code).

Structs are passed by copy in C. This can be implemented by passing a copy
of the struct (on the stack, in a register, or whatever), or by making a copy
at the call site, and passing the address of that copy. Either way, whatever
the C compiler does, the goal should be for the Ada compiler to mimic the C
compiler's method of passing structs (not pointers to structs).

Nonetheless, we choose to keep the implementation advice as is. Instead, we
solve the problem by defining a new convention, C_Pass_By_Copy:

pragma Convention (C_Pass_By_Copy, T);

The effect is that any 'in' parameter of the type T is passed by copy to a
subprogram of convention C, i.e., in a manner consistent with what C expects
if the corresponding formal in the C prototype is a struct (rather than a
pointer to a struct).

In order to make sure that this solution is portable, an implementation that
supports interfacing to C is required to support convention C_Pass_By_Copy.

Note that there is no issue for modes 'in out' and 'out'; C doesn't have
these modes, and the closest correspondence to C is a pointer-to-struct
argument.

Although this is not explicitly stated in the RM, it is clear that an Ada
function with result type T corresponds to a C function with return type t,
where t is the C type corresponding to the Ada type T.

!corrigendum B.03(1)

Replace the paragraph:

The facilities relevant to interfacing with the C language are the
package Interfaces.C and its children; and support for the Import, Export,
and Convention pragmas with convention_identifier C.

by:

The facilities relevant to interfacing with the C language are the
package Interfaces.C and its children; support for the Import, Export,
and Convention pragmas with convention_identifier C; and support
for the Convention pragma with convention_identifier C_Pass_By_Copy.

!corrigendum B.03(60)

Insert after the paragraph:

The To_C and To_Ada subprograms that convert between Wide_String
and wchar_array have analogous effects to the To_C and To_Ada
subprograms that convert between String and char_array, except that
wide_nul is used instead of nul.

the new paragraphs:

A Convention pragma with convention_identifier C_Pass_By_Copy shall
only be applied to a type.

The eligibility rules in B.1 do not apply to convention C_Pass_By_Copy.
Instead, a type T is eligible for convention C_Pass_By_Copy if T is a record
type that has no discriminants and that only has components with statically
constrained subtypes, and each component is C-compatible.

If a type is C_Pass_By_Copy-compatible then it is also C-compatible.

!corrigendum B.03(61)

Replace the paragraph:

An implementation shall support pragma Convention with a C
convention_identifier for a C-eligible type (see B.1)

by:

An implementation shall support pragma Convention with a C
convention_identifier for a C-eligible type (see B.1).
An implementation shall support pragma Convention
with a C_Pass_By_Copy convention_identifier for a
C_Pass_By_Copy-eligible type.

!corrigendum B.03(68)

Insert after the paragraph:

An Ada access T parameter, or an Ada out or in out parameter of
an elementary type T, is passed as a t* argument to a C function,
where t is the C type corresponding to the Ada type T. In the
case of an elementary out or in out parameter, a pointer to a
temporary copy is used to preserve by-copy semantics.

the new paragraph:

An Ada parameter of a C_Pass_By_Copy-compatible (record) type T,
of mode in, is passed as a t argument to a C function, where t is the
C struct corresponding to the Ada type T.

!corrigendum B.03(69)

Replace the paragraph:

An Ada parameter of a record type T, of any mode, is passed as a
t* argument to a C function, where t is the C struct
corresponding to the Ada type T.

by:

An Ada parameter of a record type T, of any mode, other than an in
parameter of a C_Pass_By_Copy-compatible type, is passed as a
t* argument to a C function, where t is the C struct corresponding to the
Ada type T.

!ACATS test

A CXC* C-Test should be created for C_Pass_By_Copy. It probably will need a
C function similar to that in CXC3013 to check that the passing was done
properly.

!appendix

!section B.3(69)
!subject Interface to C -- passing records as parameters
!reference RM95-B.3(69)
!from Bob Duff
!reference 96-5483.a Robert A Duff 96-4-13>>
!discussion
This issue was pointed out by Robert Dewar. Robert, please reply if my
message doesn't capture your understanding of the issue.
B.3(69) says:
Implementation Advice
...
69 An Ada parameter of a record type T, of any mode, is passed as a
t* argument to a C function, where t is the C struct
corresponding to the Ada type T.
The problem with this is that if one has a C function that is passed a
struct, then how can one pass an Ada record to that? One might think
that if the Ada record is passed as an 'in' parameter, it will work.
However, the above Implementation Advice implies that such an 'in'
parameter will correspond to a t* on the C side, rather than a t.
The above Advice makes sense for 'in out' and 'out' parameters, since C
doesn't have 'in out' and 'out', and t* is the closest match. However,
for 'in' parameters, it seems that an Ada record should correspond to a
C struct, rather than a C pointer-to-struct.
Note that the most important use of this interface is to take an
existing C interface, and use it from Ada code (as opposed to taking an
existing Ada interface, and mapping it to some corresponding C code).
Structs are passed by copy in C. This can be implemented by passing a
copy of the struct on the stack, or by making a copy at the call site,
and passing the address of that copy. Either way, whatever the C
compiler does, the goal should be for the Ada compiler to mimic the C
compiler.
I suspect the idea behind B.3(69) was that most C programmers, most of
the time, do *not* pass structs, but instead pass pointers-to-structs.
However, this is not universal -- passing a bare struct makes sense, and
is done in some cases.
On the other hand, if the Ada type does not directly correspond to a C
struct, it might make sense to pass it as a "t*". Examples: tagged
types, by-reference limited types, discriminated types whose size is not
known.
- Bob
****************************************************************
!section B.3(69)
!subject Interface to C -- passing records as parameters
!reference RM95-B.3(69)
!from Robert Dewar
!reference 96-5485.a Robert Dewar 96-4-13>>
!discussion
Some notes on Bob's recent post
>Structs are passed by copy in C. This can be implemented by passing a
>copy of the struct on the stack, or by making a copy at the call site,
^^^^^^^^^^^^
or in registers
>and passing the address of that copy. Either way, whatever the C
>compiler does, the goal should be for the Ada compiler to mimic the C
>compiler.
>I suspect the idea behind B.3(69) was that most C programmers, most of
>the time, do *not* pass structs, but instead pass pointers-to-structs.
>However, this is not universal -- passing a bare struct makes sense, and
>is done in some cases.
This may have been the idea, but it is wrong, it is not at all unusual
to pass struct's. An example we ran into recently occurs in the DCN
threads interface, a widely implemented industry standard. A compiler
following the referenced implementation advice could not interface to
DCN threads.
(GNAT does NOT follow this implementation advice!)
oops, it's DCE threads, not DCN!
****************************************************************
From dewar@gnat.com Mon Sep 9 22:37 EST 1996
Subject: Re: Letter Ballot #4; due 10/9/96
"I believe the summary of this should emphasize that passing by
copy only makes sense for "C" convention records. For record
types which are not explicitly marked "C" convention, I believe
the original recommendation was more generally correct, and avoids
the need to mention all the cases where by-reference passing is
required (e.g. limited record, tagged, record containing volatile,
etc.)."
I strongly disagree here, definitely something that needs to be
discussed. I believe the original recommendation was seriously
broken. The C_Pass_By_Copy pragma is a nasty kludge, but one which
inany case GNAT is copying. But I agree that in any case the
letter ballot should not pass without more discussion. So I also
vote against.
****************************************************************
From ploedere@grimm.informatik.uni-stuttgart.de Sun Sep 15 20:50 EST 1996
Subject: Re: Results of Letter Ballot #4
AI95-00131 -- Interface to C -- passing records as parameters
Taft:
Here is the only one for which I have studied the AI enough to
have a strong opinion: I believe the summary of this should
emphasize that passing by copy only makes sense for "C" convention
records. For record types which are not explicitly marked "C"
convention, I believe the original recommendation was more
generally correct, and avoids the need to mention all the cases
where by-reference passing is required (e.g. limited record,
tagged, record containing volatile, etc.).
Dewar (in reply to Taft):
I strongly disagree here, definitely something that needs to be
discussed. I believe the original recommendation was seriously
broken. The C_Pass_By_COpy pragma is a nasty kludge, but one which
inany case GNAT is copying. But I agree that in any case the
letter ballot should not pass without more discussion. So i also
vote against.
****************************************************************
From action@sw-eng.falls-church.va.us Sun May 4 13:01 EST 1997
Date: Sun, 4 May 97 08:53:18 EDT
From: dewar@gnat.com (Robert Dewar)
Subject: Re: Agenda Items for June 2 Meeting of WG9
<<The possible actions are:
1. Confirm the RM. The argument in favor is the "too late for the change"
argument, since existing bindings relying on by-reference passing would
be affected.
2. Fix the RM to alter the Advice to by-value passing. The argument in favor
is that this matches the C standard and that interfacing to all C routines
becomes possible.
2.a. As an alternative to 2, it has been proposed to advise by-value only
for record types with convention C, thus slightly ameliorating the
incompatibility.
3. Follow the action of (at least) two Ada implementations which are
providing implementation-defined pragmas to achieve by-value passing of
records. In this case, form and semantics of the pragma should be
specified. (The "too late" argument applies here as well, since the
two implementations are rumored to have different semantics.)
>>
At this stage, it is out of the question for GNAT to change what it is
doing now. We already changed once, from position 2.a to position 3, to
be compatible with Ada Magic as a result of ARA discussions, and this
change was extremely disruptive to our users. At this much later stage,
to change again would be inconceivably disruptive. Since in any case we
are discussing advice, there is no requirement to follow it anyway.
There are thus two possibilities if the ARG changes to 2.a
1) No compilers follow this advice, in which case, at least the ARG ruling
is harmless.
2) Some compilers other than GNAT do follow the advice. In this case the
effect of the ARG ruling is to break the consensus we achieved at the ARA
meeting in favor of 3. This would be a wholly negative accomplishment, and
would cause major incomaptibilities in real life!
Yes, of course the RM is seriously mistaken here -- I complained
about this very early on, and tried, by making GNAT to the right
thing (namely 2.a) to push a fix, but Ada Magic insisted on 3, and
at the time of the ARA discussion, we felt that compatibility was
more important than purity, so I agreed that GNAT would change.
I will strongly argue against 2 or 2.a at this stage at all levels of the
process. Unlike most ARG discussions, which are very unlikely to affect
users, this discussion has the potential to do real damage.
My position is as follows:
1. The ARG should NOT agree to 2 or 2.a
2. If it does, I will argue strongly that WG9 should reject this
3. If WG9 accepts this, I will argue strongly that vendors should ignor
the advice.
The ARA has not achieved much so far, but the one thing it has achieved is
getting implementations to be uniform in this critical area, and on the
pragma C_Pass_By_Copy (and the associated convention for record types).
****************************************************************
From ploedere@kafka.informatik.uni-stuttgart.de Tue Jul 1 08:44:04 1997
Date: Tue, 1 Jul 1997 14:44:25 +0200 (MET DST)
Subject: Excerpts WG-9 Minutes
Calling Conventions
At issue is the parameter passing convention for records passed to a
subprogram with convention C (AI-131). The RM contains Implementation
Advice to use by-reference passing in this case. B.3(69). However, the
C standard passes structs by-value. While this Implementation Advice
models the C programming idiom to often pass structs by reference,
i.e., as t* rather than t, and hence is a convenience in many cases,
it also makes it impossible to interface to a C routine that does not
adhere to this idiom.
The possible actions are:
* 1. Confirm the RM. The argument in favor is the "too late for the
change" argument, since existing bindings relying on by-reference
passing would be affected.
* 2. Fix the RM to alter the Advice to by-value passing. The argument in
favor is that this matches the C standard and that interfacing to all C
routines becomes possible.
* 2.a. As an alternative to 2, it has been proposed to advise by-value
only for record types with convention C, thus slightly ameliorating the
incompatibility.
* 3. Follow the action of (at least) two Ada implementations which are
providing implementation-defined pragmas to achieve by-value passing of
records. In this case, form and semantics of the pragma should be
specified. (The "too late" argument applies here as well, since the two
implementations are rumored to have different semantics.)
The ARG is split on the issue. In Montreux, 2/2a was the preferred
alternative, in Vermont opinion swayed to 1, in Henley it received a 2:3:5
vote.
Discussion at this meeting included the following salient points.
In real terms, this is really a uniformity issue. Should there be
Implementation Advice (which is relatively weak)? Action 3.b. was
added; it was similar to 3, above except that the pragma(s) would be
specified.
There was some discussion about whether or not real Ada bindings
should have an access type to the C struct, whether or not it is
implemented as call-by-value; but for the quick-and-dirty bindings, we
should be compatible with the C language standard. It would remain as
Implementation Advice, though.
Action 2.b. was added. Make it a Binding Interpretation and reference
the C language standard.
We finally agreed to a straw vote (for the ARG) on the following two
actions:
1. Make call-by-value mandatory (reference the C standard).
The individuals present voted 13-1-1.
2. Use mandatory pragma(s).
The individuals present voted 6-1-8.
The following resolution passed 8-0-0.
RESOLUTION: It should be possible to write portable bindings to C
programs. The ARG is requested to propose an appropriate mechanism.
****************************************************************
From ploedere@droste.informatik.uni-stuttgart.de Fri Nov 21 12:36 EST 1997
Date: Fri, 21 Nov 1997 13:36:10 +0100 (MET)
Subject: Minutes of St. Louis meeting
AI-131
Erhard cites the WG-9 resolution of the subject of interfacing AIs
and once again questions the summary of this AI because it
doesn't follow the C language standard. Someone reminded the
meeting that Robert D. has influenced the current decision because
of the large base of users for GNAT. Erhard argues that this
being an Implementation Advice, GNAT would be free to ignore it,
but he believes that the current advice is plainly wrong for an
ISO standard and should be corrected. Ted suggests that the user
should be encouraged to use a pragma, like the one described in
the AI, for forcing the convention for parameter passing. Gary
proposes that this AI which deals with both implementation advice
and language interfaces may be best handled by the newly proposed
WG-9 rapporteur group dealing with interfacing issues. There were
objections to the currently described pragma C_Pass_By_Copy which
focuses on data size; instead there is a preference for making the
pragma convention-based, making it apply to all usages of the
Convention C. Ted will rewrite this AI to support the Convention
approach.
****************************************************************
From bobduff@world.std.com Mon Nov 24 22:06 EST 1997
Date: Mon, 24 Nov 1997 17:05:02 -0500
Subject: Re: Minutes of St. Louis meeting
> AI-131
>
> Erhard cites the WG-9 resolution of the subject of interfacing AIs and once
> again questions the summary of this AI because it doesn t follow the C
> language standard. Someone reminded the meeting that Robert D. has
influenced
> the current decision because of the large base of users for GNAT. Erhard
> argues that this being an Implementation Advice, GNAT would be free to
ignore
> it, but he believes that the current advice is plainly wrong for an ISO
> standard and should be corrected.
Bob Duff replied that we shouldn't make rulings that we believe compiler
vendors will ignore, and the ACVC will fail to enforce.
Ted suggests that the user should be
> encouraged to use a pragma, like the one described in the AI, for forcing
the
> convention for parameter passing. Gary proposes that this AI which deals
with
> both implementation advice and language interfaces may be best handled by
the
> newly proposed WG-9 rapporteur group dealing with interfacing issues.
There
> were objections to the currently described pragma C_Pass_By_Copy which
focuses
> on data size; instead there is a preference for making the pragma
> convention-based, making it apply to all usages of the Convention C. Ted
will
> rewrite this AI to support the Convention approach.
****************************************************************
From baker@dad.cs.fsu.edu Fri Dec 12 18:53 EST 1997
Date: Fri, 12 Dec 1997 18:53:42 GMT
Subject: AI 131, on C by-value struct parameters
Robert and Tuck,
You two were not at the ARG meeting, but I believe you both
are critical to the resolution of this AI.
I was assigned the job of rewriting AI95-00131, which deals with
the interfacing of C struct parameters. I need your help, to make
sure what I write will be acceptable to you.
The gist of what I propose is:
1) For the default treatment of record parameters of subprograms
that are imported/exported as C-language, the Ada compiler should
follow the same conventions as the "local" C compiler -- but this is
not a requirement.
2) There should be a uniform way of specifying exactly what is
wanted, so that a user can write code that will work with any
compiler. To that end, we have:
a. If a user wants the effect of C "typname *", the user
can get this by using an explicit Ada access type for the parameter.
Compilers should include support for a convention
b. If a user wants the effect of C by-value struct parameters,
the user should specify the mode "in", and the convention
"C_Pass_By_Copy", either for the type of the parameter or for
the specific parameter. For the latter, I propose the syntax
used by GNAT, though I have not yet found where it is documented.
For background, I'll append minutes from the WG9 and ARG
discussions of this topic. The gist is that WG9 will not accept
simple reaffirmation of the (broken) ARM text, and that the last
couple of ARG meetings were not happy with the global
C_Pass_By_Copy pragma (as opposed to the convention).
--Ted Baker
The following is from the Philadelphia WG9 minutes:
| Calling Conventions
| At issue is the parameter passing convention for records passed to a
| subprogram with convention C (AI-131). The RM contains Implementation
| Advice to use by-reference passing in this case. B.3(69). However, the
| C standard passes structs by-value. While this Implementation Advice
| models the C programming idiom to often pass structs by reference,
| i.e., as t* rather than t, and hence is a convenience in many cases,
| it also makes it impossible to interface to a C routine that does not
| adhere to this idiom.
| The possible actions are:
| * 1. Confirm the RM. The argument in favor is the "too late for the
| change" argument, since existing bindings relying on by-reference
| passing would be affected.
| * 2. Fix the RM to alter the Advice to by-value passing. The argument in
| favor is that this matches the C standard and that interfacing to all
C
| routines becomes possible.
| * 2.a. As an alternative to 2, it has been proposed to advise by-value
| only for record types with convention C, thus slightly ameliorating
the
| incompatibility.
| * 3. Follow the action of (at least) two Ada implementations which are
| providing implementation-defined pragmas to achieve by-value passing
of
| records. In this case, form and semantics of the pragma should be
| specified. (The "too late" argument applies here as well, since the
two
| implementations are rumored to have different semantics.)
| The ARG is split on the issue. In Montreux, 2/2a was the preferred
| alternative, in Vermont opinion swayed to 1, in Henley it received a 2:3:5
| vote.
| Discussion at this meeting included the following salient points.
| In real terms, this is really a uniformity issue. Should there be
| Implementation Advice (which is relatively weak)? Action 3.b. was
| added; it was similar to 3, above except that the pragma(s) would be
| specified.
| There was some discussion about whether or not real Ada bindings
| should have an access type to the C struct, whether or not it is
| implemented as call-by-value; but for the quick-and-dirty bindings, we
| should be compatible with the C language standard. It would remain as
| Implementation Advice, though.
| Action 2.b. was added. Make it a Binding Interpretation and reference
| the C language standard.
| We finally agreed to a straw vote (for the ARG) on the following two
| actions:
| 1. Make call-by-value mandatory (reference the C standard).
| The individuals present voted 13-1-1.
| 2. Use mandatory pragma(s).
| The individuals present voted 6-1-8.
| The following resolution passed 8-0-0.
| RESOLUTION: It should be possible to write portable bindings to C
| programs. The ARG is requested to propose an appropriate mechanism.
Here's what Erhard captured in the minutes from the St. Louis ARG
meeting, with some comments/corrections from Bob Duff:
| > AI-131
| >
| > Erhard cites the WG-9 resolution of the subject of interfacing AIs and
once
| > again questions the summary of this AI because it doesn t follow the C
| > language standard. Someone reminded the meeting that Robert D. has
influenced
| > the current decision because of the large base of users for GNAT. Erhard
| > argues that this being an Implementation Advice, GNAT would be free to
ignore
| > it, but he believes that the current advice is plainly wrong for an ISO
| > standard and should be corrected.
| Bob Duff replied that we shouldn't make rulings that we believe compiler
| vendors will ignore, and the ACVC will fail to enforce.
| Ted suggests that the user should be
| > encouraged to use a pragma, like the one described in the AI, for forcing
the
| > convention for parameter passing. Gary proposes that this AI which deals
with
| > both implementation advice and language interfaces may be best handled by
the
| > newly proposed WG-9 rapporteur group dealing with interfacing issues.
There
| > were objections to the currently described pragma C_Pass_By_Copy which
focuses
| > on data size; instead there is a preference for making the pragma
| > convention-based, making it apply to all usages of the Convention C. Ted
will
| > rewrite this AI to support the Convention approach.
****************************************************************
From dewar@gnat.com Fri Dec 12 19:09 EST 1997
Date: Fri, 12 Dec 97 14:04:38 EST
Subject: Re: AI 131, on C by-value struct parameters
I think it is far too late on this issue to be making such substantial
changes to the reference manual. I *never* liked what was in the RM,
and always complained about it, and I definitely dislike the C_Pass_By_COpy
junk.
BUT, I think this is insufficiently broken for it to be useful to have an
AI that is directly contrary to
(a) implementation advice in the RM
(b) what is done in real implementations today
A whole bunch of code exists that relies on the RM convention at this stage,
namely that records are passed by address in the absence of the pragma.
I can say categorically that we would NOT consider changing GNAT to meet
the recommendation of this proposed AI if it continues to say:
1) For the default treatment of record parameters of subprograms
that are imported/exported as C-language, the Ada compiler should
follow the same conventions as the "local" C compiler -- but this is
not a requirement.
This is implementation advice that is the exact opposite of what is in the
RM.
Yes, it is what the RM should have said. The reason it did not was simply a
lack of understanding of the issues, but it is too late now to go changing
it.
<<b. If a user wants the effect of C by-value struct parameters,
the user should specify the mode "in", and the convention
"C_Pass_By_Copy", either for the type of the parameter or for
the specific parameter. For the latter, I propose the syntax
used by GNAT, though I have not yet found where it is documented.
>>
I strongly object to suggesting standardizing the GNAt approach here which
is based on the DEC pragmas (e.g. Import_Procedure), they are much too
strange
to standardize.
I would at most semi-standardize the ARA agreed on solution, which is
implemented by most Ada 95 compilers today, including GNAT. This does NOT
allow specification on a parameter by parameter basis, but rather on a global
basis (which you omit from your suggestion), or a type basis.
I would rather this AI stay in limbo for ever than that it come out
recommending a different course of action than the one being taken
by existing compilers.
We don't need an AI to solve this problem, it is already solved. An AI that
blesses the existing solution is mildly appealing. An AI that is inconsistent
with the existing solution is unhelpful. Moreover, it is getting later and
later, I really think Vermont was the last chance to agree on a different
solution -- we could not agree, so now it is too late to try to stop the
tide :-)
****************************************************************
From stt@inmet.com Fri Dec 12 20:28 EST 1997
Date: Fri, 12 Dec 1997 15:29:01 -0500
Subject: Re: AI 131, on C by-value struct parameters
> You two were not at the ARG meeting, but I believe you both
> are critical to the resolution of this AI.
>
> I was assigned the job of rewriting AI95-00131, which deals with
> the interfacing of C struct parameters. I need your help, to make
> sure what I write will be acceptable to you.
>
> The gist of what I propose is:
>
> 1) For the default treatment of record parameters of subprograms
> that are imported/exported as C-language, the Ada compiler should
> follow the same conventions as the "local" C compiler -- but this is
> not a requirement.
From what I have seen, there is real confusion when this issue is
discussed between "by-value/by-copy" *semantics* versus
passing of an address (perhaps of a temp) at run-time.
The "size" oriented semantics of the configuration pragma
C_Pass_By_Copy (as opposed to the *convention* C_Pass_By_Copy)
adds to the confusion, unfortunately.
Let me try to explain my *personal* position on this problem,
and why we ended up proposing the C_Pass_By_Copy pragmas as we did.
My experience with C is that passing "structs" by copy is relatively
rare, and returning structs is even rarer. By coincidence, our
Ada front end (which is written in ANSI C) *does* pass and return
2-word structs by copy -- a lot. When we have compiled this with various
C compilers, our heavy use of of by-value struct parameters/returns
has been the major source of problems. We have found bugs in this
area in almost every compiler we have used (including gcc, Green Hills
C, acc, Metrowerks C, etc.).
This all seems to back up my own experience that passing/returning
structs by value is not an extremely heavily used feature in C.
On the other hand, since we use it ourselves, I certainly
recognize that struct param/return is used by some programmers,
and in some programs, heavily used. Of course, for the purpose of
interoperability, we are more worried about how struct by-value
params/returns appears in the kinds of APIs that an Ada programmer
might be trying to use. Well, as it turns out, they appear in our
old friend win32.
So we thought how to best support *semantic* pass-by-value. We
concluded that, in general, in a given program or API, a given
*type* was generally either (almost) always passed by value or
(almost) always passed by reference/pointer. Hence, we wanted a
per-type approach, rather than a per-parameter approach.
Furthermore, we noticed that there seemed to be some rule of thumb
in operation, that structs above a certain size, the
programmers/API designers chose to always pass by
reference/pointer rather than by-value. This size rule-of-thumb
was *not* intended to have *anything* to do with the
implementation mechanism of struct parameter passing in the local
compiler. However, at least once, I confused myself into
believing it was determined by the size cutoff in the compiler for
passing in registers, as opposed to on the stack, or perhaps on
the stack versus passsing a pointer to a temp.
Certainly now my mind is crystal clear that the size cutoff should
have *nothing* to do with the implementation mechanism used by the
C compiler. It is simply recognizing that in most C coding
conventions, there is a size above which programmers are strongly
discouraged from using pass by value given the inherent overhead.
Got to go now; more later...
-Tuck
****************************************************************
From baker@dad.cs.fsu.edu Sun Dec 14 18:40 EST 1997
Date: Sun, 14 Dec 1997 18:40:37 GMT
Subject: Re: AI 131, on C by-value struct parameters
There seems to be an impasse here, Robert. What you are proposing went up
from the ARG to WG9, and was rejected. Is there some compromise?
--Ted
****************************************************************
From dewar@gnat.com Sun Dec 14 19:01 EST 1997
Date: Sun, 14 Dec 97 13:56:48 EST
Subject: Re: AI 131, on C by-value struct parameters
<<There seems to be an impasse here, Robert. What you are proposing went up
from the ARG to WG9, and was rejected. Is there some compromise?
>>
Yes, do nothing at all, I am pretty sure that any proposal at this stage
other than what I suggested makes no sense and would thus also be defeated.
The RM is not badly broken here, the ARG is not in the business of extending
the language, my advice is forget to do anything about it!
****************************************************************
From baker@dad.cs.fsu.edu Sun Dec 14 19:09 EST 1997
Date: Sun, 14 Dec 1997 19:09:30 GMT
Subject: what to do about AI 131?
One of my action items from the St. Louis ARG meeting was to revise AI 131.
I contacted Robert Dewar and Tucker Taft, who were not at the meeting but
clearly have important perspectives on this issue, to see what they thought.
You will recall that WG9 rejected the current draft AI, asking for
a solution that supports writing portable applications that interface
to C subprograms with struct parameters.
Robert Deware proposes to "shelve" this AI forever:
| ... do nothing at all, I am pretty sure that any proposal at this stage
| other than what I suggested makes no sense and would thus also be defeated.
| The RM is not badly broken here, the ARG is not in the business of
extending
| the language, my advice is forget to do anything about it!
Is this acceptable to the rest of the ARG, or should I proceed with
some sort of revision?
--Ted Baker
****************************************************************
From dewar@gnat.com Sun Dec 14 19:16 EST 1997
Date: Sun, 14 Dec 97 14:12:04 EST
Subject: Re: what to do about AI 131?
<<| ... do nothing at all, I am pretty sure that any proposal at this stage
| other than what I suggested makes no sense and would thus also be defeated.
| The RM is not badly broken here, the ARG is not in the business of
extending
| the language, my advice is forget to do anything about it!
>>
Ted gave my conclusion without my reasoning.
I said that the only reasonable solution at this point was one that was
(a) consistent with the RM and did not change it
(b) if extensions are proposed like pragmas, they should be consistent
with ARA agreed on practice.
Basically the ARA decided that the RM was not sufficiently broken to need
fixing, and that adding a pragma solved the problem. The various Ad 95
vendors have agreed to implement this prgma (ACT and Intermetrics have
already done so).
I think the solution chosen is ugly, and I thought so 18 months ago when we
agreed
on it, but at that time Aonix said their solution was set in stone, and could
not be changed, so ACT felt it was better to have a common solution, even if
it was clearly flawed compared to the ideal solution.
The solution agreed on is not beautiful, but it is workable.
Ted told me that the ARG was thinking along the lines of solutions that would
violate both (a) and (b) above, which i find completely unacceptable.
Certainly I can guarantee that ACT will not pay any attention to any such AI,
we cannot
afford to upset existing customers with gratuitous changes in this kind of
area.
****************************************************************
From dewar@gnat.com Mon Dec 15 00:07 EST 1997
Date: Sun, 14 Dec 97 19:03:14 EST
Subject: Re: what to do about AI 131?
Bob said
<<IMHO, the ARG shouldn't make rulings that we know vendors will ignore,
unless there's a plan to enforce it via ACVC. Better to make rulings
that the vendors can buy into. In this particular case, I tend to agree
with Robert -- the ARG should merely bless the current status quo. But
that perhaps violates the direction we've gotten from WG9, at least in
spirit.
>>
But eh ARA approach is basically
(a) to agree with the implementation advice in the RM
(b) to implement an implementation defined pragma
I see no reason why either of these should require an AI. We knoew about this
problem before we agreed on the standard, and decided not to get worked
up about it, why get worked up about it now?
****************************************************************
From baker@dad.cs.fsu.edu Mon Dec 15 00:35 EST 1997
Date: Mon, 15 Dec 1997 00:35:48 GMT
Subject: Re: what to do about AI 131?
It seems to me that the main issue here is simply that we have an AI,
and WG9+ARG have a mechanism that expects every AI to eventually be
resolved in some form at WG9. WG9 does not like the solution, so the
AI is presently in limbo. Robert is proposing that it be permanently
kept in limbo.
If all the ARG members agree with Robert on this, I would revise
the AI to state this explicitly (is there a disposition category
"no action"?). If not, then it is not clear where to go next.
I also propose to revise the discussion to give prominence to
the convention-based treatment applied to a type, rather than
the pragma that applies to all the C struct parameters over a
given size.
--Ted Baker
****************************************************************
From dewar@gnat.com Mon Dec 15 00:55 EST 1997
Date: Sun, 14 Dec 97 19:50:29 EST
Subject: Re: what to do about AI 131?
<<I also propose to revise the discussion to give prominence to
the convention-based treatment applied to a type, rather than
the pragma that applies to all the C struct parameters over a
given size.
>>
Well for me the configuration pragma is quite interesting, because if you
use it with an essentially infinite value, then you get the semantics that
the RM should have recommended in the first place. Namely that, as in C,
if you want to passa a struct, you pass a struct (record), and if you want
to pass a pointer-to-srtuct, you pass a pointer-to-struct (access-to-record).
This is obviously what the impl advice in the RM *should* have said, but
did not.
****************************************************************
From baker@dad.cs.fsu.edu Mon Dec 15 13:56 EST 1997
Date: Mon, 15 Dec 1997 13:55:51 GMT
Subject: Re: what to do about AI 131?
| <<I also propose to revise the discussion to give prominence to
| the convention-based treatment applied to a type, rather than
| the pragma that applies to all the C struct parameters over a
| given size.
| >>
| Well for me the configuration pragma is quite interesting, because if you
| use it with an essentially infinite value, then you get the semantics that
| the RM should have recommended in the first place. Namely that, as in C,
| if you want to passa a struct, you pass a struct (record), and if you want
| to pass a pointer-to-srtuct, you pass a pointer-to-struct (access-to-
record).
| This is obviously what the impl advice in the RM *should* have said, but
| did not.
Why not, then eliminate (or make optional) the parameter?
In any case, I don't like this pragma.
If one accepts your previous arguments for continuing to
make by-reference the default for interface C record parameters -- i.e.,
that people have already written code/components that rely on this --
then any globally acting pragma that changes the convention for
all subprograms is dangerous. The danger is if one combines modules
that assume one convention with modules that require the other.
The type-based convention pragma seems to me to be much less likely
to run into this problem.
--Ted
****************************************************************
From dewar@gnat.com Mon Dec 15 15:23 EST 1997
Date: Mon, 15 Dec 97 10:19:00 EST
Subject: Re: what to do about AI 131?
Erhard says
<<Great. Then pass it on to the ARG as the ARA proposal for a "standard"
extension to the standard. That's the intent of such a commonly agreed
proposal, isn't it ?
>>
My understanding is that this exactly what happened, but that WG9 rejected
this solution. I thnk it is very important that someone be present at the
ARG meeting and the subseqequent WG9 meeting who is also fully aware of
what is going on wrt ARA here, sounds like communication lines have got
messed up here!
****************************************************************
From ploedere@droste.informatik.uni-stuttgart.de Mon Dec 15 15:13 EST 1997
Date: Mon, 15 Dec 1997 16:13:22 +0100 (MET)
Subject: Re: what to do about AI 131?
> But we are talking about a case where the vendors have formally met,
discussed
> the issue, and in the context of an industry association (the ARA) have
> agreed to a common solution, and have/(are in the progress of) implemejting
> a common solution.
Great. Then pass it on to the ARG as the ARA proposal for a "standard"
extension to the standard. That's the intent of such a commonly agreed
proposal, isn't it ?
Erhard
****************************************************************
From dewar@gnat.com Mon Dec 15 16:34 EST 1997
Date: Mon, 15 Dec 97 11:29:32 EST
Subject: Re: what to do about AI 131?
<<That argument ignores the fundamental fact that once a feature is
implemented in a certain way by even one vendor, there is no way
short of major battles (with at least one loser) to standardize it
any other way, AND if more than one vendor implements a given
feature even in slightly different ways there is no hope of them
agreeing to change that.
Your remarks about pragma C_Pass_By_Value, including the Aonix
position which you mention, do indicate pretty clearly what we can
expect from Ada vendors if we rely on them for the future
evolution of the language.
>>
Ted, don't let best be the enemy of good.
This was an important problem to solve, and the vendors moved quickly
to solve it in a coordinated way a long time ago. Perhaps the solution
is not ideal, but as the ARG has found, finding an ideal solution in the
presence of this clear and intentional decision in the RM to do things
the way it does is not so easy.
If we had had to wait for the ARG here, we STILL would have no solution.
Personally, I find the C_Pass_By_Copy feature, orignally designed by
Tuck, to be quite adequate. It is in wide use now, and this seems a case
in which things worked quite fine.
Another such example is Unchecked_Union (note that your complain about
not being able to interface to certain C programs is equally applicable
there).
I think development by evoluation will work just fine. I think the
ability of the ARG to act as an aggressive source of ideas and solutions
is unrealistic. The ARG meets far too incfrequently to be able to move
rapidly, as we have seen, and I think that's just fine.
****************************************************************
From dewar@gnat.com Mon Dec 15 16:35 EST 1997
Date: Mon, 15 Dec 97 11:30:54 EST
Subject: Re: what to do about AI 131?
<<That argument ignores the fundamental fact that once a feature is
implemented in a certain way by even one vendor, there is no way
short of major battles (with at least one loser) to standardize it
any other way, AND if more than one vendor implements a given
feature even in slightly different ways there is no hope of them
agreeing to change that.
>>
Ted, I just don't think you are aware of the ARA dynamics here, I think
that the ARA process will work just fine for this and similar problems.
For example, the Unchecked_Union pragma seems quite reasonable to me,
solves an important problem, and was smoothly agreed on in the ARA
context (as far as I know the Unchecked_UNion problem isn't even on the
ARG radar yet!)
****************************************************************
From stt@inmet.com Mon Dec 15 17:42 EST 1997
Date: Mon, 15 Dec 1997 12:32:53 -0500
Subject: Re: what to do about AI 131?
I think the major problem is that the debate at the ARA level
occurred quite a while ago. That debate was cordial, and at
that time vendors were willing to compromise a bit. However,
now that the decision is long past, it feels troublesome to have
the ARG trying to alter that decision.
It is still not clear whether the ARG or an ARA group is
the best way to deal with agreeeing on common implementation-dependent
pragmas and attributes. If they *both* try to do it, that will
almost certainly result in these kinds of conflicts, unless they
operate at almost the same time with almost the same membership.
-Tuck
****************************************************************
From dewar@gnat.com Mon Dec 15 22:51 EST 1997
Date: Mon, 15 Dec 97 17:45:52 EST
Subject: Re: what to do about AI 131?
I prefer (1). As far as I know there is no official ARA document, the
ARA members seem to be more in the mode of getting things done, than
generating paper. But the description of how C_Pass_By_Copy works for
GNAT exactly matches the ARA decision as far as I know. I suggest copying
this text, then running it by Tuck to see if he agres that this is what
we agreed on.
****************************************************************
From bobduff@world.std.com Mon Dec 15 20:01 EST 1997
Date: Mon, 15 Dec 1997 15:01:31 -0500
Subject: Re: what to do about AI 131?
> If all the ARG members agree with Robert on this, I would revise
> the AI to state this explicitly (is there a disposition category
> "no action"?).
Yes, there is a "no action" class. However, I think "confirmation" is
more appropriate for this particular AI, since the original question is
a legitimate one, and deserves an answer. I think "no action" is for
cases where the question doesn't even deserve an answer.
There is no notion in the ARG of dropping AI's on the floor. We can
call them "no action", or we can assign them to the "silly questions AI"
invented by Pascal, but it's against ARG policy to simply delete them
without a trace.
I think this AI should be a confirmation. I think the answer in this
case should agree with what the ARA decided, even if the ARG doesn't
like it. There are two ways to do that: (1) The AI could confirm the
language as is, and in addition explicitly bless the C_Pass_By_Copy
feature. Or (2) the AI could confirm the language as is, and not
mention C_Pass_By_Copy. I prefer (1). However, as far as I can tell,
the ARG hasn't seen the official ARA decision.
- Bob
****************************************************************
From baker@dad.cs.fsu.edu Mon Dec 15 20:12 EST 1997
Date: Mon, 15 Dec 1997 20:12:39 GMT
Subject: Re: what to do about AI 131?
| But we are talking about a case where the vendors have formally met,
discussed
| the issue, and in the context of an industry association (the ARA) have
| agreed to a common solution, and have/(are in the progress of) implemejting
| a common solution.
I guess this "formal" meeting of the ARA vendors must have
produced some sort of document that decribes what was agreed upon
for the solution. (If not, then I question whether the the solution
being implemented is really common.) It is precisely this document that
I was hoping we could see, and use as the basis for a revised AI.
--Ted Baker
****************************************************************
From dewar@gnat.com Mon Dec 15 23:06 EST 1997
Date: Mon, 15 Dec 97 18:01:45 EST
Subject: Re: what to do about AI 131?
<<I guess this "formal" meeting of the ARA vendors must have
produced some sort of document that decribes what was agreed upon
for the solution. (If not, then I question whether the the solution
being implemented is really common.) It is precisely this document that
I was hoping we could see, and use as the basis for a revised AI.
>>
FOrmal documents are not necessary for agreements. We worked with the email
from Tuck describing the feature, and agreed to implement it as described
there. Here is the documentation from the GNAT users manual that coipes
the proposal exactly as far as I know (actually this is from the GNAT
reference manual):
@cindex Passing by copy
@findex C_Pass_By_Copy
@item pragma C_Pass_By_Copy ([Max_Size =>] @var{static_integer_expression})
Normally the default mechanism for passing C convention records to C
convention subprograms is to pass them by reference, as suggested by RM
B.3(69). Use the configuration pragma @code{C_Pass_By_Copy} to change
this default, by requiring that record formal parameters be passed by
copy if all of the following conditions are met:
@itemize @bullet
@item
The size of the record type does not exceed @var{static_integer_expression}.
@item
The record type has @code{Convention C}.
@item
The formal parameter has this record type, and the subprogram has a
foreign (non-Ada) convention.
@end itemize
If these conditions are met the argument is passed by copy, i.e. in a
manner consistent with what C expects if the corresponding formal in the
C prototype is a struct (rather than a pointer to a struct).
You can also pass records by copy by specifying the convention
@code{C_Pass_By_Copy} for the record type, or by using the extended
@code{Import} and @code{Export} pragmas, which allow specification of
passing mechanisms on a parameter by parameter basis.
****************************************************************
From dewar@gnat.com Tue Dec 16 00:25 EST 1997
Date: Mon, 15 Dec 97 19:20:32 EST
To: arg95@sw-eng.falls-church.va.us, eachus@mitre.org
<< While I have no problem agreeing that the pragma C_Pass_By_Copy works,
pragma Convention(C_Pass_By_Copy, Some_Record_Type) is certainly the more
Ada-like approach. Can we reverse the order of exposition in the AI, or is
the convention part GNAT specific, and not part of the ARA agreement?
>>
Both are part of the ARA agreement, I have no problem with emphasizing the
C_Pass_By_COpy convention over the pragma, or even not mentioning the
pragma. It won't make any difference, btu if it makes people
feel that somehow things are
being done in a more correct fashion, fine :-)
****************************************************************
From ncohen@us.ibm.com Tue Dec 16 04:18 EST 1997
Date: Mon, 15 Dec 1997 23:17:09 -0500
Subject: Re: what to do about AI 131?
Bob Duff wrote:
<<I think this AI should be a confirmation. I think the answer in this case
should agree with what the ARA decided, even if the ARG doesn't like it.
There
are two ways to do that: (1) The AI could confirm the language as is, and in
addition explicitly bless the C_Pass_By_Copy feature. Or (2) the AI could
confirm the language as is, and not mention C_Pass_By_Copy. I prefer (1).>>
So do I. But more importantly, when the ARG reports this action back to WG9,
we should call attention to it and state that we anticipate many more cases
in
which the preferred solution will be to accept a de facto consensus that has
emerged among implementors. We should then ask WG9 to formulate an
appropriate
mechanism for dealing with such cases, because this is really a matter of WG9
policy rather than ARG technical judgment.
One possible mechanism for WG9 is to form a new URG, but one whose role is to
bless uniformities that have been agreed upon by implementors rather than to
try to impose uniformities upon them. Such blessed uniformities could become
part of some official WG9 report.
The reason we might want to bother doing this is purely political: There are
some people who might object that a problem cannot be solved by standard
means
(even if all CURRENT implementations happen to use the same
implementation-defined solution), but would happily settle for a solution
that
has an ISO imprimatur, even if it is only a nonbinding recommendation.
-- Norman
****************************************************************
From phl@Rational.Com Tue Dec 16 10:24 EST 1997
Date: Tue, 16 Dec 1997 11:23:35 +0000
Subject: Re: what to do about AI 131?
> FOrmal documents are not necessary for agreements. We worked with the email
> from Tuck describing the feature, and agreed to implement it as described
> there. Here is the documentation from the GNAT users manual that coipes
> the proposal exactly as far as I know (actually this is from the GNAT
> reference manual):
>
> ...
>
> You can also pass records by copy by specifying the convention
> @code{C_Pass_By_Copy} for the record type, or by using the extended
> @code{Import} and @code{Export} pragmas, which allow specification of
> passing mechanisms on a parameter by parameter basis.
Although you seem to dislike formal documents these days, I still find the
above description for convention C_Pass_By_Copy awfully vague.
We (Rational Software) have not yet implemented this C_Pass_By_Copy thing.
Of
course, we are not going to reinvent the wheel, so we would like to implement
the same semantics as GNAT/Intermetrics. But I am sorry to say that, after
reading the above 4 lines 5 times, I still don't know what I should
implement.
Is C_Pass_By_Copy allowed for non-record types? For by-reference types?
Are
types in Interfaces.C C_Pass_By_Copy-compatible?
Surely the answers to these questions were clear when Tuck and you discussed
this topic, but they cannot be deduced from the above prose.
I don't think that anybody is proposing that the ARG invent a mechanism
different from the one invented by the ARA. But I see a lot of value in
having an AI that gives a precise definition of this convention. A common
mechanism which is not well-specified doesn't improve uniformity among
vendors: there can be as many portability problems as if each vendor had
invented their own mechanism.
To summarize, I am strongly opposed to closing this AI as "no action" or as a
confirmation merely quoting the GNAT documentation. This AI should refine
the
definition of the convention, in a way which is acceptable to all the vendors
who have already implemented it (and if we cannot find such a definition,
then
we have a problem).
Pascal
PS: I only mentioned the convention, because I cannot get excited by the
pragma, but if people think that the AI should also define the semantics of
the pragma, that's OK with me.
****************************************************************
From dewar@gnat.com Tue Dec 16 10:54 EST 1997
Date: Tue, 16 Dec 97 05:49:12 EST
Subject: Re: what to do about AI 131?
One thing to make clear is that Rational was involved in the ARA discussions
and agreed to the wording of the proposal from Intermetrics and Aonix. I
agree it would be useful to refine this, and I think it is a good idea for
the AI in question to attempt to do so.
In answer to the questions, C_Pass_By_Copy is allowed as a convention only
for records (that seeems clear from the documentation, which I am not for
a moment suggesting be the wording of the AI!) It is allowed for any record.
The types in Interfaces.C are not relevant here, I don't understand what
Pascal means by asking if these types are C_Pass_By_Copy compatible.
Certainly this pragma is not needed in conjuncion with Interfaces.C.
One thing to remember is that it is fairly rare to pass records by copy in
C, but there are indeed casees in the Posix binding.
I am a little surprised that Rational has not impleemented this, since at
the meeting they indicated they would, but I guess priorities get set by
customers as usual :-)
One thing to ask for here is the Aonix documentation (since Aonix and
Intermetrics were the proposers of this design!)
****************************************************************
From ploedere@droste.informatik.uni-stuttgart.de Tue Dec 16 17:27 EST 1997
Date: Tue, 16 Dec 1997 18:27:07 +0100 (MET)
Subject: To all Implementors !! was: Re: what to do about AI 131?
I agree with Pascal and I'am urging all the implementors listening in to
look at the pragma proposal, state their position and ask their questions,
so that somebody can refine the proposal to a reasonably unambiguous
specification.
Erhard
****************************************************************
From eachus@mitre.org Tue Dec 16 21:03 EST 1997
Date: Tue, 16 Dec 1997 16:03:50 -0500
Subject: Re: what to do about AI 131?
At 07:20 PM 12/15/97 EST, Robert Dewar wrote:
>Both are part of the ARA agreement, I have no problem with emphasizing the
>C_Pass_By_COpy convention over the pragma, or even not mentioning the
>pragma. It won't make any difference, btu if it makes people
>feel that somehow things are being done in a more correct fashion, fine :-)
Not more correct, but it should be the default choice. If you can use
the per type C_Pass_By_Copy, it doesn't burn other users, and doesn't have
configuration control problems. The Import and Export arguments are
occaisionally needed, but trying to do everything with them in a large
interface would be a maintenance headache. If you use the configuration
pragma, that minimizes the work if you are developing just for yourself,
but can cause headaches if you are building a component of a larger system.
However, the real reason I would like to see it appear first, is that it
is the easiest to understand. You are declaring a record type that must
map to a C type that the C compiler passes by copy, it is not hard to
understand that you want to say pragma Convention (C_Pass_By_Copy, foo)
instead of pragma Convention (C, foo).
****************************************************************
From jmk7hj31@aurora.cdev.com Tue Dec 16 22:18 EST 1997
Date: Tue, 16 Dec 1997 16:18:28 -0600
From: Mike Kamrad <J.M.KAMRAD.II@cdev.com>
Subject: Re: To all Implementors !! was: Re: what to do about AI 131?
At 6:27 PM +0100 12/16/97, Erhard Ploedereder wrote:
>I agree with Pascal and I'am urging all the implementors listening in to
>look at the pragma proposal, state their position and ask their questions,
>so that somebody can refine the proposal to a reasonably unambiguous
>specification.
>
>Erhard
I, too, agree with Pascal...mike
****************************************************************
From baker@dad.cs.fsu.edu Tue Dec 16 22:21 EST 1997
Date: Tue, 16 Dec 1997 22:21:09 GMT
Subject: Re: what to do about AI 131?
| One thing to ask for here is the Aonix documentation (since Aonix and
| Intermetrics were the proposers of this design!)
Yes. To whom at Aonix should I direct this request?
--Ted
PS:
Your proposed model for ARA setting "standards" for the vendors still
lacks plausibility, because you apparently have no documentation for these
"agreements". In this case, I have it directly from you and Tuck that
your current implementations do not exactly agree on the details of this
feature, and we now see that "Rational" agreed to something but did not
follow it up and apparently does not currently have a record of what was
agreed upon. This situation is not surprising, given that you apparently
are relying on the individual memories of the people who participated in
your original ARA meeting on this subject. Individual people forget, and
sometimes they switch jobs.
If the ARA is going to make this work, it will need to document the
agreements, and keep an archive of them---- i.e., produce something
similar to the AI's.
--Ted
****************************************************************
From dewar@gnat.com Wed Dec 17 03:55 EST 1997
Date: Tue, 16 Dec 97 22:51:02 EST
Subject: Re: To all Implementors !! was: Re: what to do about AI 131?
What puzzles me is the following: According to Ted, the substance of
the proposal that WG9 turned down was precisely a precise characterization
of something approximating the current Aonix/GNAT implementation of
C_Pass_By_Copy.
Is this true?
If so, aren't we barking up the wrong tree to say let's do it again!
Incidentally, I would have been delighted to have a more formal
definition of the feature. All we had was a rough description by
email, and we did our best to conform to it, but no one disagrees
that it would be nice to have a more formal document. However,
given that this was meeting a rather critical need, we definitely
did put the need to implement rapidly ahead of formalism (although
to me the GNAT documentation is pretty clear, and certainly we never
had any difficulty in users understanding or using this feature).
****************************************************************
From stt@inmet.com Wed Dec 17 06:14 EST 1997
Date: Wed, 17 Dec 1997 01:14:21 -0500
Subject: Re: To all Implementors !! was: Re: what to do about AI 131?
> Incidentally, I would have been delighted to have a more formal
> definition of the feature. All we had was a rough description by
> email, and we did our best to conform to it, but no one disagrees
> that it would be nice to have a more formal document.
For what it is worth, I believe Vince DelVecchio wrote up a formal
definition of C_Pass_By_Copy and put it on the "ACE" (Ada Common Environment)
web-site, which at least for a while was being maintained by OCSystems.
-Tuck
****************************************************************
From phl@Rational.Com Wed Dec 17 10:19 EST 1997
Date: Wed, 17 Dec 1997 11:18:12 +0000
Subject: Re: what to do about AI 131?
> The types in Interfaces.C are not relevant here, I don't understand what
> Pascal means by asking if these types are C_Pass_By_Copy compatible.
> Certainly this pragma is not needed in conjuncion with Interfaces.C.
Consider:
type T1 is record ... end record;
pragma Convention (C_Pass_By_Copy, T1);
type T2 is access procedure (X : T1; Y : Interfaces.C.Int);
pragma Convention (C_Pass_By_Copy, T2); -- Legal?
For the pragma Convention on T2 to be legal, Interfaces.C.Int has to be
C_Pass_By_Copy-compatible, as per RM95 B.1(18).
I have no doubt that the types in Interfaces.C should be
C_Pass_By_Copy-compatible (but that should be stated in the AI). However,
things become more delicate when you consider user-defined types, because
there is no way to state that a type is compatible with several conventions
(a
hole in the language IMHO). Consider:
type T3 is range ...;
pragma Convention (C, T3);
type T4 is access procedure (X : T1; Y : T3);
pragma Convention (C_Pass_By_Copy, T4); -- Legal?
Assume that you cannot change the convention for T3, maybe because it's in a
3rd-party package. Then if we don't do anything, the pragma Convention on T4
is illegal.
It seems that we should decide that any type which is C-compatible is also
C_Pass_By_Copy-compatible, and (perhaps) vice-versa.
It seems to me that these questions are relevant and worth discussing.
Pascal
****************************************************************
From dewar@gnat.com Wed Dec 17 13:00 EST 1997
Date: Wed, 17 Dec 97 07:55:14 EST
Subject: Re: what to do about AI 131?
<<Consider:
type T1 is record ... end record;
pragma Convention (C_Pass_By_Copy, T1);
type T2 is access procedure (X : T1; Y : Interfaces.C.Int);
pragma Convention (C_Pass_By_Copy, T2); -- Legal?
For the pragma Convention on T2 to be legal, Interfaces.C.Int has to be
C_Pass_By_Copy-compatible, as per RM95 B.1(18).
>>
In our implementation, C_Pass_By_Copy only has special meaning for record
types, and is otherwise treated as a synonym for C, but I think it would
be equally reasonable to just disallow it for anything other than records.
****************************************************************
From ploedere@droste.informatik.uni-stuttgart.de Wed Dec 17 13:43 EST 1997
Date: Wed, 17 Dec 1997 14:43:18 +0100 (MET)
Subject: Re: what to do about AI 131?
> What puzzles me is the following: According to Ted, the substance of
> the proposal that WG9 turned down was precisely a precise characterization
> of something approximating the current Aonix/GNAT implementation of
> C_Pass_By_Copy.
>
> Is this true?
No, this is not true. I reiterate: WG9 has not really discussed that
proposal. And, the pragma proposal was in no way made more precise than
what we got from GNAT or wherever.
What WG9 saw was a presentation of the problem of AI-131 (at the London
meeting), as requested by WG9 (at the Phila. meeting) in response to the ARG
request for guidance on this issue. WG9 in London then summarily refused to
discuss merits of individual solutions of the specific issue, relegating it
back to ARG with the general resolution that you saw. WG9 was not made aware
of the pragma solution being an official ARA proposal; neither was I aware
of that.
My personal understanding at the time was that this was a fairly quickly
hashed out solution that involved only GNAT and Intermetrics, combined with
rumors that the two implementations then proceeded to implement it with
somewhat differing semantics.
So much for history, now to the future...The WG9 resolution implies to me
that WG9 wants to be presented with a solution that is common among vendors.
To be common, its semantics need to be commonly agreed upon by the vendors
(preferred) or be put forth by the ARG, based on input from the vendors and
playing the arbitration role among conflicting views (hopefully not).
To call this a "no action" item is esentially admitting defeat by saying
"no, there is no common definition possible".
Erhard
****************************************************************
From dewar@gnat.com Wed Dec 17 13:51 EST 1997
Date: Wed, 17 Dec 97 08:46:16 EST
Subject: Re: what to do about AI 131?
<<What WG9 saw was a presentation of the problem of AI-131 (at the London
meeting), as requested by WG9 (at the Phila. meeting) in response to the ARG
request for guidance on this issue. WG9 in London then summarily refused to
discuss merits of individual solutions of the specific issue, relegating it
back to ARG with the general resolution that you saw. WG9 was not made aware
of the pragma solution being an official ARA proposal; neither was I aware
of that.
>>
Ah, OK, I misunderstood Ted's message then. Incidentally, when we discussed
this in Vermont, I certainly explained that the C_Pass_By_Copy was the
ARA agreed on approach, but I guess this got lost :-)
This sure sounds like one that it would be helpful for me to be there
for the discussion :-)
When *is* the next ARG meeting by the way?
****************************************************************
From: Erhard Ploedereder[SMTP:ploedere@informatik.uni-stuttgart.de]
Sent: Wednesday, May 06, 1998 7:07 PM
Subject: Re: AI 131, revisited
Based on all the words in the appendix, I don't think that this AI will
fly (at least not with me) unless the semantics of the pragma are
stated in detail. Questions like:
-- effect on Ada parameter passing of actuals of such type
-- applies to derived types ? subtypes ?
-- illegal for non-record types ?
-- applicable to tagged types ?
-- interactions with Convention C ?
usw. usw.
Erhard
****************************************************************
From: Ted Baker
Sent: Wednesday, May 06, 1998 5:52 PM
Subject: Re: AI 131, revisited
Erhard,
Thanks for the feedback. I have no problem filling in details,
though I'm surprised that you think they are needed, given:
(1) the previously ARG-approved AI (with the pragma C_Pass_By_Copy)
had no more detail;
(2) B.1 already specifies the general rules for convention pragmas,
and sets no precedent for further details;
(3) we are supposed to be capturing what the vendors are currently
already doing, but the vendors have not cooperated in providing
me any more detailed semantics.
Item (3) the biggie!! No sense in playing guessing games here,
proposing detailed semantics and then being told by the vendors
that they object because it will require them to change their
implementations.
The above being said, if you really insist on answering these
questions, here are some ideas, for continuing the discussion:
| Based on all the words in the appendix, I don't think that this AI will
| fly (at least not with me) unless the semantics of the pragma are
| stated in detail. Questions like:
| -- effect on Ada parameter passing of actuals of such type
I would limit the effect parameters of interfaced C subprograms,
so parameters cannot be passed further to subprograms that do not
have this convention.
| -- applies to derived types ? subtypes ?
I would limit the effect to parameters declared to be of the named
subtype.
| -- illegal for non-record types ?
| -- applicable to tagged types ?
I would not require support or define the effect except for
non-tagged record types.
Note that by B.1 (13-20) tagged types are not "eligible for
convention" unless a particular implementation chooses to allow
them. (BTW, I don't see any harm in allowing implementations to
extend the applications of convention C_Pass_By_Copy, though I
have no strong feeling on it.)
| -- interactions with Convention C ?
I would not define the effect if more than one convention is
specified for a given subtype.
| usw. usw.
Wieso weiter? I just can't respond to such an open-ended ending.
I'll wait until I see some more comments before offering a revised
AI.
--Ted
****************************************************************
From: Jean-Pierre Rosen[SMTP:rosen.adalog@wanadoo.fr]
Sent: Thursday, May 07, 1998 1:47 AM
To: arg95@ns1.sw-eng.falls-church.va.us
Subject: Re: AI 131, revisited
>| Based on all the words in the appendix, I don't think that this AI will
>| fly (at least not with me) unless the semantics of the pragma are
>| stated in detail. Questions like:
>
>| -- effect on Ada parameter passing of actuals of such type
>
>I would limit the effect parameters of interfaced C subprograms,
>so parameters cannot be passed further to subprograms that do not
>have this convention.
>
Well, it should at least also apply to exported Ada procedures...
----------------------------------------------------------------------------
J-P. Rosen (Rosen.Adalog@wanadoo.fr)
Visit Adalog's web site at http://perso.wanadoo.fr/adalog
****************************************************************
From: Robert Dewar
Sent: Thursday, May 07, 1998 6:00 AM
Subject: Re: AI 131, revisited
<<Well, it should at least also apply to exported Ada procedures...
>>
Only if they have Convention C!
****************************************************************
From: Ted Baker[SMTP:baker@dad.cs.fsu.edu]
Sent: Thursday, May 07, 1998 7:25 AM
Subject: Re: AI 131, revisited
| >| -- effect on Ada parameter passing of actuals of such type
| >
| >I would limit the effect parameters of interfaced C subprograms,
| >so parameters cannot be passed further to subprograms that do not
| >have this convention.
| >
| Well, it should at least also apply to exported Ada procedures...
This is an interesting philosophical question. What is the right
default convention for parameters of an exported subprogram? When
one imports a subprogram into Ada, one expects the parameters to
be passed according to the convention of the foreign language.
Should one not then, by symmetry, expect that if a subprogram is
exported from Ada to a foreign language then the foreign language
should expect the parameters to be passed according to the Ada
conventions? I guess this is not a symmetric world, i.e., Ada
compilers care about importing C functions but C compilers don't
care about being able to import Ada subprograms.
Given that things are not symmetric, it does make sense to allow
the convention C_Pass_By_Copy to apply to parameters of Ada
procedures exported to C as well as C procedures imported to Ada.
--Ted
****************************************************************
From: Robert Dewar[SMTP:dewar@gnat.com]
Sent: Thursday, May 07, 1998 7:47 AM
Subject: Re: AI 131, revisited
Of course! Absolutely it is the case that exported procedures with
convention C are affected! This is the case in current implementations
most certainly!
****************************************************************
From: Pascal Leroy
Sent: Thursday, November 05, 1998 8:43 AM
Subject: Re: AI-00131
> That's confusing, the issue is not really pass by copy or not, since
> C always passes by copy. The issue is passing this in a manner compatible
> with a parameter of type struct on the C side. The existing implementation
> advice is written in this style, so the AI should also use this language.
You're right. I was trying to make the summary simple and it's actually
inaccurate. I believe that the wording in other sections of the AI is
correct. It seems that the second paragraph of the summary should be replaced
by:
"An implementation which supports interfacing to C shall support pragma
Convention with a C_Pass_By_Copy identifier. An 'in' parameter of a
C_Pass_By_Copy-compatible type T should be passed as a t argument to a C
function, where t is the C struct corresponding to type T."
Pascal
****************************************************************
From: Pascal Leroy[SMTP:phl@RATIONAL.COM]
Sent: Friday, November 06, 1998 5:26 AM
Subject: Re: AI-00131: function results
I am looking at AI-00131 again, and I am puzzled by the following issue:
In ANSI C, a function can return a struct (of course, it can also return a
pointer to a struct). The RM (i.e., the implementation advice in B.3(63-71))
doesn't offer any guidance regarding the correspondance between the return
type of a C function and the return type of the corresponding Ada function.
The situation is quite clear in the case of scalars, but in the case of
structs, it seems that the RM as it stands doesn't make it possible to write a
portable interface (since it specifies nothing, the behavior is presumably
implementation-defined). Should C_Pass_By_Copy also apply to function
results? Or am I missing something?
Pascal
****************************************************************
From: Robert Dewar[SMTP:dewar@GNAT.COM]
Sent: Friday, November 06, 1998 6:52 AM
Subject: Re: AI-00131: function results
I think it is quite wrong for an Ada function that specifies a record to
be returned to accept a pointer-to-record, that seems strange. It would
mean that an implicit dereference had to occur, which just seems wrong
to me. This is quite different from the IN parameter case, where the
corespondence is between call-by-reference on the Ada side, and passing
pointers byt value on the C side.
There is no return-by-reference (at least not in the sense that would be
relevant here).
So I think it is clear that this is NOT controlled by the pragma, if you
specify that a function returns a record on the Ada side, then it must
return a struct on the C side.
****************************************************************
From: Pascal Leroy[SMTP:phl@RATIONAL.COM]
Sent: Friday, November 06, 1998 9:15 AM
Subject: Re: AI-00131: function results
> if you
> specify that a function returns a record on the Ada side, then it must
> return a struct on the C side.
That's a very reasonable statement, but I still find worrisome that the RM
doesn't say a word on this topic.
Pascal
****************************************************************
From: Tucker Taft[SMTP:stt@INMET.COM]
Sent: Friday, November 06, 1998 10:40 AM
Subject: Re: AI-00131: function results
I think there is the usual confusion between what the C source code
looks like, and what the generated machine code looks like.
When a struct is returned at the source level, at the generated
machine code level, C often does the same thing that Ada does,
have the caller pass in a pointer to a place on the stack where
the result should be placed.
If the object is sufficiently small, then rather than using a
caller-allocated stack temp for the function result, one or more
registers are used. The question is whether one purpose of this
pragma (or perhaps some alternative one we invent) is to distinguish
between these two approaches at the machine code level, or
whether we presume that the Ada compiler should "know" enough about
the C compiler(s) on the target to make the right choice without
direction.
This is analogous to the parameter passing case, though in that
case there are three alternatives at the machine code level for
something which at the C source code level is by-value (rather
than by pointer): pass in registers if sufficiently short, push onto
the stack if medium size, and pass a pointer to a temp if very large.
I think the C_Pass_By_Copy pragma has always suffered from
a confusion between the source issues and the machine-level issues.
It partly stems from the fact that some Ada compilers "know" more
about how the target C compiler works, or there is a standard
ABI, while other Ada compilers know less about the target C compiler
and are using pragmas (like this one) to figure out what to do.
Hopefully this AI would clarify the situation somewhat.
-Tuck
****************************************************************
From: Robert Dewar[SMTP:dewar@GNAT.COM]
Sent: Friday, November 06, 1998 8:33 AM
Subject: Re: AI-00131: function results
<<That's a very reasonable statement, but I still find worrisome that the RM
doesn't say a word on this topic.
Pascal
>>
Doesn't worry me, the RM is totally broken in this area anyway. Better it
say nothing than make a horrible mistake saying the wrong thing, as was the
case with records passed as parameters.
As long as implementations do the right thing, who cares what the RM says
in implementation advice? What is troublesome is when the RM has wrong
advice :-)
Certainly the AI can most certainly clean this up, but this AI is not a
terribly important one anyway, since it only affects impl advice.
The critical issue here wrt Pass_By_Copy has not been what the RM says,
because that can be ignored, since it is impl advice, but rather trying
to make compilers do the same thing.
I personally think C_Pass_By_Copy is a horrible kludge. Nothing the RM
says will change my mind. The reason we implemented it was to be compatible
with what the IM front end did. I am not sure we made the right choice in
doing this, but for sure what the RM said was not a factor in our
thinking at all!
The AI is about matching the RM to practice, not influencing practice!
****************************************************************
From: Robert Dewar[SMTP:dewar@GNAT.COM]
Sent: Friday, November 06, 1998 11:02 AM
Subject: Re: AI-00131: function results
<<If the object is sufficiently small, then rather than using a
caller-allocated stack temp for the function result, one or more
registers are used. The question is whether one purpose of this
pragma (or perhaps some alternative one we invent) is to distinguish
between these two approaches at the machine code level, or
whether we presume that the Ada compiler should "know" enough about
the C compiler(s) on the target to make the right choice without
direction.
>>
Of course the compiler has to know how to pass parameters. It is
definitely NOT the function of the C_Pass_By_COpy pragma to tell
the compiler whether to pass in registers or not.
The C_Pass_By_Copy pragma merely means that you pass it the way
C would pass a struct, no more, no less, so I don't really see
any confusion at all here.
It is the same as for an Integer passed to a C int. the compiler has
to know whether to put this in a register, on the stack or ???
The only reason we have an issue is the injudicious advice in the RM
to do what is in fact clearly the wrong thing!
In the case of returned values, we have no bad advice to tackle, so there
is no issue. I think the AI will just confuse things if it starts talking
about the implementation level issues that Tuck raises.
The deal is simple, if you write
function q returns x;
pragma Import (q);
where x is a record type, then this must use a calling sequence compatible
with the C function
cx q();
where cx is the corresponding C struct.
No discussion of registers, stacks, or any other low level stuff is
needed. It is always the job of the Ada compiler to know how to pass
stuff according to the specified convention. A compiler that does not
know enough should NOT attempt to recognize the convention!
****************************************************************
From: Robert A Duff[SMTP:bobduff@WORLD.STD.COM]
Sent: Monday, November 09, 1998 3:28 PM
Subject: Re: AI-00131: function results
> Of course the compiler has to know how to pass parameters. It is
> definitely NOT the function of the C_Pass_By_COpy pragma to tell
> the compiler whether to pass in registers or not.
I agree with Robert. The RM, and the AI, only need to talk about what
Ada decls correspond to what C decls. There's no need to mention
anything about registers, and temporary copies that are then passed by
ref, &c -- for all that stuff, the Ada compiler just has to get it
right. Yes, that generally means the Ada compiler writer has to know
what the C compiler is going to do.
I also agree with Robert that the original RM rule that made
C_Pass_By_Copy_Necessary, was mistaken -- and I take part of the blame
for that.
- Bob
****************************************************************