How can I "re-export" an existing bind(C) function, overloaded in Fortran module, under its name with ifort?

StackOverflow https://stackoverflow.com/questions/15726633

Pregunta

I was quite happy with the construct that worked well with gfortran until I tried it with ifort. Though I have not ever seen it clearly documented. I just tried that and it worked. I'm curious though how could I adjust the following sample such that ifort 11.1 can chew it.

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

Here is an error message I'm getting

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
-----^

Is it a GNU extension? -pedantic does not complain. It works as I expect it to work

           5
   4.00000000    

Do I have to write in full details foo0 declaration inside of interface foo?

UPDATE 2013-03-31

I adjusted example code above to include bind(C). Since it resides in interface, I cannot use module even with gfortran. I apologize for misleading with improper trimmed down example previously.

Another update 2013-03-31

Apparently ifort version 13.1.1 does not support such constructs (no matter if I rename foo to foo0 or not)

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
---------------^

If I add module before procedure, I get

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

It looks like it is not currently possible to do what I want unless I explicitly declare that bind(C) interface again in all details :(

¿Fue útil?

Solución 2

With foo a C-function, it seems that foo can't be a module procedure. An intermediate function can be used as a workaround:

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

Otros consejos

It is a Fortran 2003 feature:

"When MODULE is specified, procedure-name_list can only contain module procedures. When MODULE is not specified, procedure-name_list may contain procedure pointers, external procedures, dummy procedures, or module procedures."

Your version 11.1 is obsolete, current release is 13, but I am not sure if it is supported now.

In this case it should be OK to use module procedure until your versions of compilers support Fortran 2003 fully:

"If the MODULE keyword appears, each procedure name has to be a module procedure and has to be accessible in the current scope."

source: IBM XL Fortran manual

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top