Sun Studio 12: Fortran Programming Guide

11.5 Functions That Return a Value

A Fortran function that returns a value of type BYTE , INTEGER, REAL, LOGICAL, DOUBLE PRECISION, or REAL*16 is equivalent to a C function that returns a compatible type (see Table 11–1). There are two extra arguments for the return values of character functions, and one extra argument for the return values of complex functions.

11.5.1 Returning a Simple Data Type

The following example returns a REAL or float value. BYTE, INTEGER, LOGICAL, DOUBLE PRECISION, and REAL*16 are treated in a similar way:

Table 11–12 Functions Returning a REAL or Float Value

Fortran calls C  

C calls Fortran  


real ADD1, R, S
external ADD1
R = 8.0
S = ADD1( R )
...

------------------------------

float add1_( pf )
float *pf;
{
   float f ;
   f = *pf;
   f++;
   return ( f );
}

float r, s;
extern float fadd1_() ;
r = 8.0;
s = fadd1_( &r );
...

------------------------------

real function fadd1 (p)
  real p
  fadd1 = p + 1.0
  return
end

11.5.2 Returning COMPLEX Data

The situation for interoperability of COMPLEX data differs between 32-bit implementations and 64-bit SPARC implementations.

11.5.2.1 32-bit Platforms

A Fortran function returning COMPLEX or DOUBLE COMPLEX on 32-bit platforms is equivalent to a C function with an additional first argument that points to the return value in memory. The general pattern for the Fortran function and its corresponding C function is:

Fortran function  

C function  


COMPLEX FUNCTION CF( a1,a2,...,an)

cf_ (return, a1, a2, ..., an)
 struct { float r, i; } *return

Table 11–13 Function Returning COMPLEX Data (32–bit SPARC)

Fortran calls C  

C calls Fortran  


COMPLEX U, V, RETCPX
EXTERNAL RETCPX
U = ( 7.0, -8.0)
V = RETCPX(U)
...

------------------------------

struct complex { float r, i; };
void retcpx_( temp, w )
struct complex *temp, *w;
{
   temp->r = w->r + 1.0;
   temp->i = w->i + 1.0;
   return;
}

struct complex { float r, i; };
struct complex c1, c2;<
struct complex *u=&c1, *v=&c2;
extern retfpx_();
u -> r = 7.0;
u -> i = -8.0;
retfpx_( v, u );
...

------------------------------

COMPLEX FUNCTION RETFPX(Z)
  COMPLEX Z
  RETFPX = Z + (1.0, 1.0)
  RETURN
END

11.5.2.2 64–bit SPARC Platforms

In 64-bit SPARC environments, COMPLEX values are returned in floating-point registers: COMPLEX and DOUBLE COMPLEX in %f0 and %f1, and COMPLEX*32 in %f0, %f1, %f2, and %f3. For 64–bit SPARC, a C function returning a structure whose fields are all floating-point types will return the structure in the floating-point registers if at most 4 such registers are needed to do so.The general pattern for the Fortran function and its corresponding C function on 64–bit SPARC platforms is:

Fortran function  

C function  

COMPLEX FUNCTION CF(a1, a2, ..., an)

struct {float r,i;} cf_ (a1, a2, ..., an)

Table 11–14 Function Returning COMPLEX Data (64–bit SPARC)

Fortran calls C  


COMPLEX U, V, RETCPX
EXTERNAL RETCPX
U = ( 7.0, -8.0)
V = RETCPX(U)
...

---------------------------------------------------------

struct complex {float r, i; };
struct complex retcpx_(struct complex *w )
{
    struct complex temp;
    temp.r = w->r + 1.0;
    temp.ii = w->i + 1.0;
    return (temp);
}

C calls Fortran  


struct complex { float r, i; };
struct complex c1, c2;
struct complex *u=&c1;
extern struct complex retfpx_(struct complex *);
  u -> r = 7.0;
  u -> i = -8.0;
  retfpx_( u );
...

---------------------------------------------------------

COMPLEX FUNCTION RETFPX(Z)
  COMPLEX Z
  RETFPX = Z + (1.0, 1.0)
  RETURN
END

11.5.3 Returning a CHARACTER String

Passing strings between C and Fortran routines is not encouraged. However, a Fortran character-string-valued function is equivalent to a C function with two additional first arguments—data address and string length. The general pattern for the Fortran function and its corresponding C function is:

Fortran function  

C function  

CHARACTER*n FUNCTION C(a1, ..., an)


 
void c_ (result, length, a1, ..., an)
char result[ ];
long length;

Here is an example:

Table 11–15 A Function Returning a CHARACTER String

Fortran calls C  

C calls Fortran  


CHARACTER STRING*16, CSTR*9
STRING = ’ ’
STRING = ’123’ // CSTR(’*’,9)
...

------------------------------

void cstr_( char *p2rslt,
            long rslt_len,
            char *p2arg,
            int *p2n,
            long arg_len )
{ /* return n copies of arg */
  int count, i;
  char *cp;
  count = *p2n;
  cp = p2rslt;
  for (i=0; i<count; i++) {
    *cp++ = *p2arg ;
  }
}

void fstr_( char *, long,
           char *, int *, long );
char sbf[9] = "123456789";
char *p2rslt = sbf;
int rslt_len = sizeof(sbf);
char ch = ’*’;
int n = 4;
int ch_len = sizeof(ch);
/* make n copies of ch in sbf
*/
fstr_( p2rslt, rslt_len,
       &ch, &n, ch_len );
...

------------------------------

FUNCTION FSTR( C, N)
  CHARACTER FSTR*(*), C
  FSTR = ’’
  DO I = 1,N
    FSTR(I:I) = C
  END DO
  FSTR(N+1:N+1) = CHAR(0)
END

In this example, the C function and calling C routine must accommodate two initial extra arguments (a pointer to the result string and the length of the string) and one additional argument at the end of the list (length of character argument). Note that in the Fortran routine called from C, it is necessary to explicitly add a final null character. Fortran strings are not null-terminated by default.