From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Simon Wright Newsgroups: comp.lang.ada Subject: Re: Making the same mistake as the broken C interface to fortran Date: Thu, 04 Jul 2019 09:38:23 +0100 Organization: A noiseless patient Spider Message-ID: References: <2uYSE.298383$sJ3.119314@fx04.am4> <499TE.1270744$Ud5.547915@fx12.am4> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: reader02.eternal-september.org; posting-host="85640eaf5174ff4a158fde77643582a8"; logging-data="16391"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/ZTbyMbwgsH1oFx3phDW60P4FLS1pVErk=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (darwin) Cancel-Lock: sha1:glS/HH8L8yBevQASnraM+8XWos0= sha1:HmR79mb3GbAmsWbkEFBOoFCu4LQ= Xref: reader01.eternal-september.org comp.lang.ada:56811 Date: 2019-07-04T09:38:23+01:00 List-Id: Chris M Moore writes: > On 03/07/2019 20:02, Randy Brukardt wrote: >> "Chris M Moore" 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. >> > >> >> 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.