comp.lang.ada
 help / color / mirror / Atom feed
From: Simon Wright <simon@pushface.org>
Subject: Re: Making the same mistake as the broken C interface to fortran
Date: Thu, 04 Jul 2019 09:38:23 +0100
Date: 2019-07-04T09:38:23+01:00	[thread overview]
Message-ID: <lylfxe6vpc.fsf@pushface.org> (raw)
In-Reply-To: 499TE.1270744$Ud5.547915@fx12.am4

Chris M Moore <zmower@ntlworld.com> writes:

> On 03/07/2019 20:02, Randy Brukardt wrote:
>> "Chris M Moore" <zmower@ntlworld.com> wrote in message
>> news:2uYSE.298383$sJ3.119314@fx04.am4...
>> ...
>>> So the question is do we break the API or not?
>>
>> That's not the question. The question is ensuring that the Ada
>> compiler properly implements the Fortran convention. If it does, then
>> the API doesn't change. And if it doesn't, then fix the silly
>> compiler (or get a different one that does the right thing). The
>> Annex B "Implementation Advice" (specifically, B.5(22-26)) is very
>> close to a requirement, in that the interface is not useful if one
>> can't depend on the mapping.
>>
> <snip>
>>
>> BTW, I note that type Fortran_Character is in fact an array type, so
>> that could be confusing some readers of the API (it surely would have
>> confused me).

It confused the heck out of me, too. You'd've expected a warning at
least if you use a dodgy parameter type!

I did a little poking around with GCC 9.1.0:

Fortran:

      subroutine callee (c)
      character (1), intent (in) :: c

      print *, 'parameter c is ', c

      end

Ada:

with Interfaces.Fortran;
procedure Call is
   procedure Callee_C (C : Character)
   with
     Import,
     Convention => Fortran,
     External_Name => "callee_";
   procedure Callee_F (C : Interfaces.Fortran.Fortran_Character)
   with
     Import,
     Convention => Fortran,
     External_Name => "callee_";
   procedure Callee_S (S : String)
   with
     Import,
     Convention => Fortran,
     External_Name => "callee_";
begin
   Callee_C ('c');
   Callee_F ((1 => 'f'));
   Callee_F ("F string");
   Callee_S ("A string");
end Call;

Result:

$ gfortran -c callee.f
$ gnatmake -gnatwa call.adb -largs callee.o -lgfortran
gcc -c -gnatwa call.adb
gnatbind -x call.ali
gnatlink call.ali callee.o -lgfortran
$ ./call
 parameter c is c
 parameter c is f
 parameter c is F
 parameter c is A
 
> I'm sure GNAT does the right thing if you're using
> Fortran_Character. Unfortunately the bindings use Standard.Character.

Which bindings are those? I can certainly look at changing the ones in
gnat-math-extn (Should be https://sf.net/p/gnat-math-extn, but down at
the moment), but those are entirely internal.

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

For what it's worth, the issue is that a long-standing feature of the
Fortran ABI is that 'character' is an array type, so that the fat
parameter contains (1) the address of the first element and (2) the
length of the actual (I'm not sure whether these two parts are
necessarily contiguous). If the Fortran only ever accesses the first
element, it doesn't matter if the length part is never actually passed
on the stack, which is what happens when Ada or C passes Character or
char rsp.

However, with a new optimisation, if the Fortran compiler recognises an
opportunity for "tail recursion" (or a sibling call), it reuses
the current stack arguments for the sibling call, including the length
component of the character argument. If that length component was never
actually pushed by the original caller, oops, trashed stack.

  reply	other threads:[~2019-07-04  8:38 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-24 23:33 Making the same mistake as the broken C interface to fortran Chris M Moore
2019-07-02 20:57 ` Simon Wright
2019-07-03  7:06   ` Chris M Moore
2019-07-03 19:02     ` Randy Brukardt
2019-07-03 21:31       ` Chris M Moore
2019-07-04  8:38         ` Simon Wright [this message]
2019-07-05 13:49           ` Chris M Moore
2019-07-05 17:44             ` Simon Wright
2019-07-07 16:33               ` Chris M Moore
replies disabled

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