Absoft Fortran 90 -- Gnu C99 interoperability

From: E. Robert Tisdale (E.Robert.Tisdale_at_jpl.nasa.gov)
Date: 05/19/04


Date: Wed, 19 May 2004 13:36:53 -0700


> cat f.h
         #ifndef Guard_f_h
         #define Guard_f_h 1
         typedef struct X_t {
           int I;
           } X_t;

         X_t f_(int);

         #endif/*Guard_f_h */

> cat f.c
         #include "f.h"

         X_t f_(int i) {
           X_t x;
           x.I = i;
           return x;
           }

> gcc -Wall -std=c99 -pedantic -O2 -c f.c
> cat typeX_t.f90
         module typeX_t
           implicit none
           type:: X_t
             integer i
             end type X_t
           end module typeX_t

> cat g.f90
           subroutine g(x)
             use typeX_t
             type (X_t):: x
             type (X_t), external:: f
             x = f(33)
             end subroutine g

> cat program.f90
         program main
           use typeX_t
           type (X_t):: x
           external g
           call g(x)
           print *, x%i
           end program main

> f90 -cpu:host -YCFRL=1 -YEXT_NAMES=LCS -YEXT_SFX=_ \
         -YCOM_NAMES=LCS -YCOM_PFX= -YCOM_SFX=_ \
         -O2 -o main typeX_t.f90 g.f90 program.f90 f.o
> ./main
         Segmentation fault (core dumped)
> gcc -Wall -std=c99 -pedantic -O2 -S f.c
> cat f.s
                 .file "f.c"
                 .text
                 .align 2
                 .p2align 2,,3
         .globl f_
                 .type f_,@function
         f_:
                 pushl %ebp
                 movl %esp, %ebp
                 movl 8(%ebp), %eax
                 movl 12(%ebp), %edx
                 movl %edx, (%eax)
                 leave
                 ret $4
         .Lfe1:
                 .size f_,.Lfe1-f_
                 .ident "GCC: (GNU) 3.2 20020903 \
         (Red Hat Linux 8.0 3.2-7)"

I'm having trouble calling GNU C functions
that retun a struct (derived type) by value.
The problem is that the C function pops four bytes

                 ret $4

off of the stack when it returns.
This confuses the calling Fortran subroutine g
leading to a segmentation fault and core dump
when subroutine g attempts to return.
I am told that the GNU C compiler does this

     Because that's what SYSV ABI for i386 says it should do:
     http://www.caldera.com/developers/devspecs/abi386-4.pdf
     page 40:

       Functions Returning Structures or Unions
       If a function returns a structure or union, then the caller
       provides space for the return value and places its address on the
       stack as argument word zero. In effect, this address becomes a
       "hidden" first argument. Having the caller supply the return
       object's space allows re-entrancy.

For some reason, the Absoft compiler developers have chosen
*not* to comply with the SYSV ABI for i386.
Are there any Fortran 90 compilers
for SYSV [Linux] and i386 that comply?