fortran66のブログ

fortran について書きます。

【メモ帳】Fortran 2018 C言語の相互運用 MFE §21.4

Modern Fortran Explained - 2018 §21.4 assumed character length

Fortran の文字列は文字の配列ではなく、文字列長などの付加的な情報を持っています。その情報は、C言語側で Fortran 2018 が用意したヘッダーファイルを include することで、構造体の要素として利用できるようになります。下の例で文字列長を利用しています。

c言語側で ISO_Fortran_binding.h というヘッダーファイルを読み込む必要がありますが、うまく include ディレクトリに配置してあるようで、特にコンパイル時の付加的なオプション指定は必要ないようです。

ソース・プログラム

fortran

program test
    use, intrinsic :: iso_fortran_env
    use, intrinsic :: iso_c_binding
    implicit none
    interface
        subroutine err_msg(string) bind(c, name = 'err_msg')
            use, intrinsic :: iso_c_binding
            character(len=*, kind = c_char) :: string
        end subroutine err_msg
    end interface

    character(*), parameter :: text = '***fortran characters***'

    print *, compiler_version()
    print *, compiler_options()
    print *

    call err_msg(text)

    call err_msg('ABEND: abnormal end')

    stop 'normal termination'
end program test

C

MFE のテキストでは iso_fortran_binding.h とすべて小文字になっていますが、一部大文字にしないと読んでくれませんでした。 「ISO_Fortran_binding.h」

#include <stdio.h>
#include "ISO_Fortran_binding.h"

void err_msg(CFI_cdesc_t *string) {
    char *p = string->base_addr;
    for (int len = string->elem_len; len > 0; len--) putc(*p++, stderr);
    putc('\n', stderr);
}

Modern Fortran Explained: Incorporating Fortran 2018 (Numerical Mathematics and Scientific Computation)

Modern Fortran Explained: Incorporating Fortran 2018 (Numerical Mathematics and Scientific Computation)

実行結果

gfortran-9 はバグがあります。 他の例題を見ているうち、なんとなくこういう仕様の気がしてきたw

ifort/icc は通ります。

gfortran-9

fortran の文字列は文字の配列ではないので、c 言語との互換の場合に文字の配列に制限するというが残ってしまっているようです。

hp8@HP8:~/f2018$ gfortran-9 mfe214.f90 c_mfe214.o -Wall
mfe214.f90:6:33:

    6 |         subroutine err_msg(string) bind(c, name = 'err_msg')
      |                                 1
Error: Character argument ‘string’ at (1) must be length 1 because procedure ‘err_msg’ is BIND(C)

icc/ifort

「ABEND: abnormal end」というのは冗談です。

hp8@HP8:~/f2018$ icc -traceback  -c c_mfe214.c
hp8@HP8:~/f2018$ ifort -traceback  c_mfe214.o mfe214.f90
hp8@HP8:~/f2018$ ./a.out
 Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64,
 Version 19.1.0.056 Pre-Release Beta Build 20190321
 -traceback

***fortran characters***
ABEND: abnormal end
normal termination