1

我的工作,需要存儲在Fortran語言的派生類型的屬性的內存地址的項目ifort不同的行爲。在gfortran中發現的是,如果返回是一個派生類型,那麼函數的返回就有一個隱式副本。所以我存儲的地址是沒有意義的。有一段代碼:gfortran和函數返回派生類型

module atest 
! use iso_c_binding 
    type test 
    real(8):: a 
    real(8):: p 
    end type test 
    interface 
    subroutine pointerprint(a) 
     real(8), intent(in) :: a 
    end subroutine pointerprint 
    end interface 
    interface assignment(=) 
    module procedure overloadedAsgn 
    end interface 
contains 
    function returnvalue(t) 
    type(test), intent(in)::t 
    type(test):: returnvalue 
    returnvalue%a=t%a+1 
    call pointerprint(returnvalue%a) 
    end function returnvalue 
    SUBROUTINE overloadedAsgn(ret,rhs) 
    type(test), intent(inout) :: ret 
    type(test), intent(in) :: rhs 
    print *, "assign_d" 
    ret%a=rhs%a 
    ret%p=rhs%p+1.0d0 
    call pointerprint(rhs%a) 
    end SUBROUTINE overloadedAsgn 

end module 

program xxx 
    use atest 
    type(test):: t 
    type(test):: b 
    t%a=1.0d0/11.0d0 
    t%p=0.0d0 
    b=returnvalue(t) 
end program 


#include<stdio.h> 
void pointerprint_(double *x){ 
    printf("Addr<%lx>\n",(unsigned long)x); 
} 

輸出使用gfortran是:

Addr<7fff51df24e0> 
assign_d 
Addr<7fff51df2520> 

的outpus使用ifort是:

Addr<7fffc92e6fc0> 
assign_d 
Addr<7fffc92e6fc0> 

是否有辦法避免這種複製gfortran所以結果是一致的?我剛開始學習fortran。可能有一個函數的描述符或編譯器的一個選項。

+0

你如何調用一個C代碼,如果你已經使用'iso_c_binding'註釋掉?我擔心的是C代碼接口中的某些東西是差異的根源。 – patrickvacek

回答

1

你指望依賴於處理器的行爲。如果處理器有利可圖,則可以通過複製(和/或出)來傳遞。您可以使用指針僞參數來傳遞指針。

你不必在你的代碼中的任何TARGET,仍然要靠指針的變量。

+0

這很有趣!你能詳細解釋一下嗎? (或者給一個鏈接/書,我可以看這件事?) –

+0

對於gfortran特定的約定見http://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html –

+0

否則我建議的Fortran 2008標準和信息性附錄。對於這種情況,C.9.4節是相關的(關於指向虛擬參數和'target'屬性的指針的可用性)。 –