2013-03-31 23 views
2

我對使用gfortran很好的構造感到非常滿意,直到我嘗試使用ifort。雖然我從未見過它清楚記載。我剛剛嘗試過,它工作。我很好奇,但是我怎樣才能調整下面的樣本,使ifort 11.1能夠咀嚼它。如何在Fortran模塊中重新導出現有的綁定(C)函數,並在其名稱下使用ifort?

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  

我必須在全部細節寫入foo0接口FOO內申報?

UPDATE 2013年3月31日

我調整上述例子的代碼包括bind(C)。由於它駐留在interface,因此即使使用gfortran也不能使用module。我很抱歉誤導了以前不正確的修剪。

另一個更新2013年3月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 
----------------------^ 

它看起來目前是不可能做我wa NT,除非我再次明確聲明,綁定(C)接口,所有的細節:(

+1

在模塊B中,使用語句中的重命名列表不是必需的。你可以在通用接口模塊中編寫'foo'程序,它將引用來自模塊A的函數foo。 – eriktous

+0

@ m-s-b確實,我給出的例子可以使用'module'。但它是一個簡化版本。在我的情況下,我有foo0作爲bind(C)。而且我收到一個錯誤,說'錯誤:'(1)處的'foo0'不是一個模塊過程'# – mlt

+0

@eriktous我不記得爲什麼我首先將它重命名。也許它被其他一些錯誤所掩蓋,我認爲名稱衝突,例如如同名稱的類型和模塊。 – mlt

回答

2

使用foo一個C函數,看起來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 
+0

由於我生成Fortran代碼,我最終將綁定(c)聲明放在通用接口中,而不是依靠編譯器來優化它。 – mlt

5

這是一個Fortran 2003功能:

「當指定的模塊時,過程的name_list中只能包含模塊的程序。當沒有指定MODULE時,procedure-name_list可能包含過程指針,外部過程,虛擬過程或模塊過程。「

您的11.1版已過時,當前版本爲13,但我不確定它現在是否支持。

在這種情況下,它應該是確定以使用module procedure,直到你的編譯器的版本支持的Fortran 2003全:

「如果出現模塊的關鍵字,每個程序名稱必須是一個模塊過程,並具有可訪問在當前範圍內「。

來源:IBM XL Fortran manual

+0

我更新了示例代碼,說明爲什麼我不能使用'module procedure'。如果它處於標準狀態,並且在某些時候會趕上,那對我來說就沒有問題。我會嘗試更新的ifort版本。 – mlt

相關問題