Sun Studio 12: Fortran プログラミングガイド

11.5 値を戻す関数

BYTE、INTEGER、REAL、LOGICAL、DOUBLE PRECISION、または REAL*16 型の値を戻す Fortran 関数は、互換性のある型を戻す C の関数と等価です (表 11–1 を参照)。文字関数の戻り値には引数が 2 つ追加され、複素数関数の戻り値には引数が 1 つ追加されます。

11.5.1 単純型データを戻す

次の例は REAL または float 値を戻します。BYTE、INTEGER、LOGICAL、DOUBLE PRECISION、および REAL*16 も同じような方法で扱われます。

表 11–12 REAL または float の値を戻す関数

Fortran が C を呼び出す 

C が 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 複素数データを戻す

複素数データの相互運用性に関する状況は、32 ビットの実装と 64 ビットの SPARC V9 の実装では異なります。

11.5.2.1 32 ビットプラットフォーム

32 ビットプラットフォームで、COMPLEX または DOUBLE COMPLEX を戻す Fortran 関数は、メモリーにある戻り値を指す追加の引数を最初の引数として持つ C の関数と同じです。Fortran 関数と対応する C 関数の一般的な形式は次のとおりです。

Fortran 関数 

C 関数 


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

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

表 11–13 複素数データを戻す関数 (32 ビット SPARC)

Fortran が C を呼び出す 

C が 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 ビット SPARC プラットフォーム

64 ビット SPARC 環境では、COMPLEX 値が浮動小数点レジスタに戻されます。COMPLEXDOUBLE COMPLEX はそれぞれ %f0%f1 に戻され、COMPLEX*32%f0%f1%f2、および %f3 に戻されます。64 ビット SPARC では、要素がすべて浮動小数点型の構造体を返す C 関数は、浮動小数点レジスタで構造体を返します。ただし、そのために必要なレジスタの数が 4 個以下の場合にかぎられます。Fortran 関数と対応する C 関数の一般的な形式は次のとおりです。

Fortran 関数 

C 関数 

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

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

表 11–14 複素数データを戻す関数 (64 ビット SPARC)

Fortran が 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 が 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 CHARACTER 文字列を戻す

C と Fortran ルーチンの間で文字列を渡すことは推奨できません。ただし、Fortran の文字列の値を持つ関数は、データアドレスとデータ長の 2 つの引数がはじめに追加された C の関数と同じです。Fortran 関数と対応する C 関数の一般的な形式は次のとおりです。

Fortran 関数 

C 関数 

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


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

次に例を示します。

表 11–15 CHARACTER 文字列を戻す関数

Fortran が C を呼び出す 

C が 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 )
{ /* 引数に n 個のコピーを戻す */
  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);
/* sbf 内に ch のコピーを n 個作成
*/
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

この例では、C 関数と呼び出し側の C ルーチンは、リストの最初に 2 つの引数 (結果として戻される文字列へのポインタと文字列長) が、そして、リストの最後に 1 つの追加引数 (文字列引数の長さ) が追加されています。C から呼び出された Fortran ルーチンでは最後のヌル文字を明示的に追加する必要があることに注意してください。Fortran の文字列は、デフォルトでは NULL 終端されません。