comp.lang.ada
 help / color / mirror / Atom feed
* String parameters to exported routines - What should a compiler do?
@ 1997-06-03  0:00 Kevin D. Heatwole
  1997-06-05  0:00 ` Robert A Duff
  1997-06-09  0:00 ` Tucker Taft
  0 siblings, 2 replies; 5+ messages in thread
From: Kevin D. Heatwole @ 1997-06-03  0:00 UTC (permalink / raw)



I am still struggling to figure out exactly what a compiler should do when
the Ada program contains an exported subprogram that has a parameter that
is unconstrained.  We have implemented what we thought was a reasonable
thing to do, but now I am having second thoughts.

What *should* a good Ada95 compiler do?  I don't want to know what is legal
or simply permissable, but what is expected for an Ada95 compiler.

Here is an example:

  procedure S (Item : String);
  pragma Export (C, S);

Should this be legal or should the declaration of S be rejected?  

If legal, should the compiler issue a warning that calling S from C
involves passing the bounds of item in a compiler-dependent form?

Or, should the compiler just generate code for the body of S that expects
Item to just be the  address of the first character that comprise the
string and the bounds are assumed to be Positive'First .. Positive'Last (or
whatever the bounds are on the index subtype)?

Would the answers to the above make any difference if the parameter's type
was Interfaces.C.Char_Array?

What if S were called by Ada instead of C?  Should the Ada call pass the
actual bounds to S whereas the C call gets away with just passing the
address of Item?

Finally, what if S were imported instead?  Should Ada calling S just pass
the address of the first character of Item and just omit the bounds
altogether? 

What do other Ada95 compilers do?

Sorry for all the questions but I want to make sure that we handled this
case in the best manner possible.  We are about to make major release of
our PowerAda compiler and I don't want to miss an opportunity to make this
"right" (if we don't already handle this "right").

Kevin Heatwole
OC Systems, Inc.




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: String parameters to exported routines - What should a compiler do?
  1997-06-03  0:00 String parameters to exported routines - What should a compiler do? Kevin D. Heatwole
@ 1997-06-05  0:00 ` Robert A Duff
  1997-06-07  0:00   ` Robert Dewar
  1997-06-09  0:00 ` Tucker Taft
  1 sibling, 1 reply; 5+ messages in thread
From: Robert A Duff @ 1997-06-05  0:00 UTC (permalink / raw)



In article <heatwole-ya02408000R0306972356360001@news3.his.com>,
Kevin D. Heatwole <heatwole@his.com> wrote:
>I am still struggling to figure out exactly what a compiler should do when
>the Ada program contains an exported subprogram that has a parameter that
>is unconstrained.

Assuming the other language has reasonable support for arrays that carry
their bounds with them, then of course you ought to mimic what the other
compiler is doing.

Oh, you say you're interfacing to C, which has no such support.  ;-)
Well, then, hem, haw.

>Here is an example:
>
>  procedure S (Item : String);
>  pragma Export (C, S);
>
>Should this be legal or should the declaration of S be rejected?  

IMHO it should be legal.

>If legal, should the compiler issue a warning that calling S from C
>involves passing the bounds of item in a compiler-dependent form?

Well, maybe.  Many users might be helped by this warning.  On the other
hand, the problem with warnings like that (i.e. warnings that only
*sometimes* mean that something is wrong) is that the compiler never
learns.  I recompile my program 1000 times, and the compiler *still*
doesn't understand that my code is just what I meant -- it warns me 1000
times, by which time my brain has learned to ignore all warnings.  If
you have a way to turn off individual warnings, that problem is solved.

>Or, should the compiler just generate code for the body of S that expects
>Item to just be the  address of the first character that comprise the
>string and the bounds are assumed to be Positive'First .. Positive'Last (or
>whatever the bounds are on the index subtype)?

B.3(70) seems to say that you should be passing the address of the first
array component.  But it doesn't address the issue of what Item'Last
should be, or whether (how?) index checking should be done.  On the
other hand, B.3(70) is a "should" rule, so perhaps you can ignore it in
this case, and expect the bounds where you normally do.  The C could
would then have to know how to pass bounds as extra parameters.

IMHO, if the bounds are going to be "wrong", then the programmer should
be doing the "cheating" -- that is, pass an argument of subtype
"String(Positive)", and carefully avoid relying on the bounds.

>Would the answers to the above make any difference if the parameter's type
>was Interfaces.C.Char_Array?

Good question.

>What if S were called by Ada instead of C?  Should the Ada call pass the
>actual bounds to S whereas the C call gets away with just passing the
>address of Item?

I don't see how that can work (unless you're willing to generate two
copies of the code for procedure S).  I mean, either it expects bounds
or not.  And the C compiler doesn't know how to produce any bounds -- if
bounds are expected, the C programmer has to produce them.

>Finally, what if S were imported instead?  Should Ada calling S just pass
>the address of the first character of Item and just omit the bounds
>altogether? 

It seems like whatever the answer is, imports and exports should have
the same calling conventions.  I mean, you can form pointers to these
things, and if the the access type is convention C, then that's all you
know -- you don't know whether the thing it points to is "really"
written in C.

Import seems more important than export, though.  I mean, it's more
common to want to write an Ada program that interfaces to some existing
(say) windowing system, than the other way around.

>What do other Ada95 compilers do?

Well, it shouldn't be hard to figure out what GNAT does (by reading docs
and/or looking at the source code).  Probably your best bet is to mimic
other compiler(s).  Another thing to do would be to take existing
bindings (e.g. win32) and make sure whatever they do works.  Probably,
they never care -- they probably pass only constrained array subtypes.

>Sorry for all the questions but I want to make sure that we handled this
>case in the best manner possible.  We are about to make major release of
>our PowerAda compiler and I don't want to miss an opportunity to make this
>"right" (if we don't already handle this "right").

What do you do now?

Likewise, how do you deal with "access String" when interfacing?
That's a similar issue.

- Bob




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: String parameters to exported routines - What should a compiler do?
  1997-06-05  0:00 ` Robert A Duff
@ 1997-06-07  0:00   ` Robert Dewar
  0 siblings, 0 replies; 5+ messages in thread
From: Robert Dewar @ 1997-06-07  0:00 UTC (permalink / raw)



Bob Duff said

<<>Here is an example:
>
>  procedure S (Item : String);
>  pragma Export (C, S);
>
>Should this be legal or should the declaration of S be rejected?  
 
IMHO it should be legal.
>>

and then goes on to mumble about what it might actually mean :-) :-)

In my view this should be illegal. One could supply default bounds, e.g.
in this case 1 .. Natural'Last, but I do not consider this helpful. If you
want to deal with the type

  subtype Big_String is String (Natural);

then it is better to do so explicitly





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: String parameters to exported routines - What should a compiler do?
  1997-06-03  0:00 String parameters to exported routines - What should a compiler do? Kevin D. Heatwole
  1997-06-05  0:00 ` Robert A Duff
@ 1997-06-09  0:00 ` Tucker Taft
  1997-06-10  0:00   ` Robert Dewar
  1 sibling, 1 reply; 5+ messages in thread
From: Tucker Taft @ 1997-06-09  0:00 UTC (permalink / raw)



Kevin D. Heatwole (heatwole@his.com) wrote:

: I am still struggling to figure out exactly what a compiler should do when
: the Ada program contains an exported subprogram that has a parameter that
: is unconstrained.  We have implemented what we thought was a reasonable
: thing to do, but now I am having second thoughts.

It is not a question of whether or not the subprogram is exported.
Rather, it is a question of the "convention" specified in the
Export, Import, or Convention pragma.

: What *should* a good Ada95 compiler do?  I don't want to know what is legal
: or simply permissable, but what is expected for an Ada95 compiler.

: Here is an example:

:   procedure S (Item : String);
:   pragma Export (C, S);

: Should this be legal or should the declaration of S be rejected?  

This should be legal.

: If legal, should the compiler issue a warning that calling S from C
: involves passing the bounds of item in a compiler-dependent form?

The bounds should not be passed because the specified convention 
is "C" which does not pass bounds.

: Or, should the compiler just generate code for the body of S that expects
: Item to just be the  address of the first character that comprise the
: string and the bounds are assumed to be Positive'First .. Positive'Last (or
: whatever the bounds are on the index subtype)?

This is what I would recommend.  Use the bounds of the index subtype.

: Would the answers to the above make any difference if the parameter's type
: was Interfaces.C.Char_Array?

No.

: What if S were called by Ada instead of C?  Should the Ada call pass the
: actual bounds to S whereas the C call gets away with just passing the
: address of Item?

No, the bounds should not be passed in either case.  (Unless you have
two entry points, I can't quite imagine how you could pass the bounds
in one case, and not in the other.)

: Finally, what if S were imported instead?  Should Ada calling S just pass
: the address of the first character of Item and just omit the bounds
: altogether? 

Import vs. export is irrelevant.  What matters is the "convention."

If the convention specifies a language that doesn't pass implicit
array bounds (or accessibility level, or the "'Constrained" bit)
on the given target, then they should not be passed.  

For export, you need to "manufacture" the information, and for array 
bounds, using the index subtype seems best.  For accessibility level, presume
library level, and for 'Constrained, presume unconstrained.  In other
words, assume the most flexible answer, and let the user pass other 
explicit parameters if necessary to determine the "true" bounds, 
accessibility, etc., as would be required in C or other descriptor-less 
languages.

: What do other Ada95 compilers do?

The suggestions above conform to the AdaMagic-based compilers.  I believe
GNAT uses the same approach, though presumably an ACT person can give
you the official answer.

Note that for Java, length is passed along with the array, so you
only need to "manufacture" the low bound (from the index subtype); the 
high bound can be computed.

: Sorry for all the questions but I want to make sure that we handled this
: case in the best manner possible.  We are about to make major release of
: our PowerAda compiler and I don't want to miss an opportunity to make this
: "right" (if we don't already handle this "right").

: Kevin Heatwole
: OC Systems, Inc.

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: String parameters to exported routines - What should a compiler do?
  1997-06-09  0:00 ` Tucker Taft
@ 1997-06-10  0:00   ` Robert Dewar
  0 siblings, 0 replies; 5+ messages in thread
From: Robert Dewar @ 1997-06-10  0:00 UTC (permalink / raw)



Tuck says

<<This is what I would recommend.  Use the bounds of the index subtype.
>>


I strongly disagree. I think this is error prone, and no, GNAT does NOT do
this, and regards the construct as illegal or generates a warning, I can't
remember which right now, I think in fact it should be illegal.

If you pass a string from a C program to an exported Ada program, e.g.
"abc", and you allow a construct with String as a formal on the Ada side,
typical programmers who do not understand the issues will expect the bounds
to be 1..3, and their programs will go berserk overwriting memory when they
use 'Range. It should never be this easy to import this kind of overwriting
into an Ada program.

If you want the effect that Tuck recommends, then get it by defining a type

   subtype Big_String is String (Natural);

and use this as the type. These kind of types (we always call them Big_xxx
by convention in the GNAT sources) are often useful in dealing with cases
where bounds are simply not available. They have the advantage of constantly
reminding the programmer that the bounds are NOT available.

Yes, I know AdaMagic supplies bounds in this case, and we considered doing
this in GNAT as well, but rejected the idea as too dangerous, per above
reasoning.

Generally it is of course desirable for Ada 95 compilers to do the same
think in the same situation, but it is not an absolute principle, and when
compilers do things that are outside the RM (you cannot deduce Tuck's 
recommendation from the RM), they should not always be copied.

Sometimes it seems reasonable to copy things. For example, even though
the AdaMagic C_Pass_By_Copy facility is a bit of a kludge (a sufficient
kludge that the ARG cannot yet bring itself to endorse this as the
proper solution to the error in the RM, see below), it seemed reasonable
to copy this into GNAT, and indeed the ARA (not quite so bound as the ARG
by considerations of elegance :-) decided that this should be the common
approach.

P.S. the RM error I refer to above is the recommendation that all structs
should be passed by reference. This was a plain mistake, since it would
forbid compilers from duplicating the typical C callings sequence in which
small structs are passed by copy in registers. 
(we are talking here specifically about passing mechanisms for convention C)

Finally, Tuck says there is no difference between export and import with
regard to the original topic.

That's quite wrong.

Importing functions is not a problem. It is fine to discard bounds on the
way to C, since C does not expect the bounds anyway. On the other hand,
exporting is a real problem. Here we have no bounds on the C side.

Tuck recommends implicitly generating bogus bounds on the way to Ada
GNAT feels that it is safer not to allow the notation, given that it
adds danger, but no expressive power.





^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1997-06-10  0:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-06-03  0:00 String parameters to exported routines - What should a compiler do? Kevin D. Heatwole
1997-06-05  0:00 ` Robert A Duff
1997-06-07  0:00   ` Robert Dewar
1997-06-09  0:00 ` Tucker Taft
1997-06-10  0:00   ` Robert Dewar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox