2

在我尝试使用 ifort 之前,我对与 gfortran 配合良好的构造感到非常满意。虽然我从未见过它清楚地记录在案。我刚试过,它奏效了。我很好奇如何调整以下示例,以便 ifort 11.1 可以咀嚼它。

module A
  use iso_c_binding
  implicit none

  interface
     function foo(x) bind(C, name="strlen")
       use, intrinsic :: iso_c_binding
       character(c_char), intent(in) :: x
       integer(c_size_t) :: foo
     end function foo
  end interface

end module A

module B
  use A
!  use A, foo0 => foo
  implicit none

  interface foo
     module procedure foo1
     procedure foo
  end interface foo

contains

  function foo1(x)
    real, intent(in) :: x
    real :: foo1
    foo1 = 2. * x
  end function foo1

end module B

program C
  use B
  implicit none

  write (*,*) foo(C_CHAR_"Hello" // C_NULL_CHAR)
  write (*,*) foo(2.)

end program C

这是我收到的错误消息

tst.f90(20): error #6643: This statement is incorrectly positioned.
     procedure foo0
-----^
tst.f90(20): error #8168: Parentheses are required after the PROCEDURE keyword.
     procedure foo0
-----^

它是 GNU 扩展吗?-pedantic不抱怨。它像我期望的那样工作

           5
   4.00000000    

我是否必须在接口 foo 中详细编写 foo0 声明?

更新 2013-03-31

我调整了上面的示例代码以包含bind(C). 由于它位于 中,因此即使与 gfortran 一起interface使用也无法使用。module对于之前不恰当的精简示例误导我深表歉意。

另一个更新 2013-03-31

显然ifort version 13.1.1不支持这样的构造(无论我是否将 foo 重命名为 foo0 )

tst.f90(22): error #6623: The procedure name of the INTERFACE block conflicts with a name in the encompassing scoping unit.   [FOO]
     procedure foo
---------------^
tst.f90(22): error #8574: A procedure-name in a generic interface block must be a nonintrinsic procedure that has an explicit interface.   [FOO]
     procedure foo
---------------^

如果我module在程序之前添加,我会得到

tst.f90(22): error #7950: Procedure name in MODULE PROCEDURE statement must be the name of accessible module procedure.   [FOO]
     module procedure foo
----------------------^

除非我在所有细节中再次明确声明该 bind(C) 接口,否则目前似乎无法做我想做的事:(

4

2 回答 2

5

这是 Fortran 2003 的一个功能:

“指定 MODULE 时,procedure-name_list 只能包含模块过程。未指定 MODULE 时,procedure-name_list 可能包含过程指针、外部过程、伪过程或模块过程。”

您的 11.1 版本已过时,当前版本为 13,但我不确定现在是否支持。

在这种情况下,应该可以使用module procedure,直到您的编译器版本完全支持 Fortran 2003:

“如果出现 MODULE 关键字,则每个过程名称必须是模块过程,并且必须在当前范围内可访问。”

来源:IBM XL Fortran 手册

于 2013-03-31T08:10:33.357 回答
2

使用fooC 函数,似乎foo不能成为模块过程。可以使用中间函数作为解决方法:

module A
  use, intrinsic :: iso_c_binding
  implicit none

  interface
     function strlen(x) bind(C, name="strlen")
       use, intrinsic :: iso_c_binding
       character(kind=c_char, len=1), dimension (*), intent(in) :: x
       integer(c_size_t) :: strlen
     end function strlen
  end interface

contains

function foo (x)
   character(kind=c_char, len=*), intent(in) :: x
   integer (c_size_t) :: foo
   foo = strlen (x)
end function foo

end module A

module B
  use A
!  use A, foo0 => foo
  implicit none

  interface foo
     module procedure foo1
     module procedure foo
  end interface foo

contains

  function foo1(x)
    real, intent(in) :: x
    real :: foo1
    foo1 = 2. * x
  end function foo1

end module B

program C
  use B
  implicit none

  write (*,*) foo(C_CHAR_"Hello" // C_NULL_CHAR)
  write (*,*) foo(2.)

end program C
于 2013-03-31T22:53:03.797 回答