簡體   English   中英

純Fortran程序中的I / O.

[英]I/O in pure Fortran procedures

我正在嘗試將錯誤檢查納入我正在編寫的純過程中。 我想要像:

pure real function func1(output_unit,a)
    implicit none
    integer :: a, output_unit

    if (a < 0) then
        write(output_unit,*) 'Error in function func1: argument must be a nonnegative integer. It is ', a
    else
    func1 = a/3

    endif
    return
end function func1

但是,不允許純函數將IO語句賦予外部文件,因此我嘗試將單元號傳遞給函數,例如output_unit = 6 ,這是默認輸出。 gfortran仍然認為這是非法的。 有沒有解決的辦法? 是否有可能使函數成為派生類型(而不是內部類型為real ),在出現錯誤時輸出字符串?

您不是第一個遇到此問題的人,我很高興地說,標准中的這個缺陷將在Fortran 2015中得到糾正。如本文檔所述 (第6頁,標題為“批准的標准更改”), “應該刪除對pure過程中error stop語句的出現的限制”

Fortran 2008標准在一些新的並行計算功能的上下文中包含了error stop語句。 它發出錯誤信號,並在可行的情況下盡快停止所有進程。 目前,既沒有stop ,也沒有error stop語句也可以在pure程序,因為它們顯然不是線程安全的。 實際上,在發生內部錯誤的情況下,這是不必要的限制。

根據您的編譯器,您可能需要耐心等待實施。 我知道英特爾已經在他們的ifort編譯器中實現了它。 “F2015:在PURE / ELEMENTAL程序中對STOP和ERROR STOP的提升限制”

替代

對於另一種方法,你可以看看這個問題 ,但在你的情況下這可能有點棘手,因為你必須改變do concurrent關鍵字,而不僅僅是pure

(正確答案結束)

如果弄臟手是一種選擇......

與此同時,你可以做一些殘酷的事情

pure subroutine internal_error(error_msg)
    ! Try hard to produce a runtime error, regardless of compiler flags.
    ! This is useful in pure subprograms where you want to produce an error, 
    ! preferably with a traceback.
    ! 
    ! Though far from pretty, this solution contains all the ugliness in this 
    ! single subprogram.
    ! 
    ! TODO: replace with ERROR STOP when supported by compiler
    implicit none

    character(*), intent(in) :: error_msg

    integer, dimension(:), allocatable :: molested

    allocate(molested(2))
    allocate(molested(2))
    molested(3) = molested(4)
    molested(1) = -10
    molested(2) = sqrt(real(molested(1)))
    deallocate(molested)
    deallocate(molested)
    molested(3) = molested(-10)
end subroutine internal_error

如果有人問,你沒有從我這里得到這個。

我已經找到了答案我自己,詳細介紹在這里 它使用被認為是“過時”的東西,但仍然可以做到這一點; 它被稱為替代回報。 將過程編寫為子例程,因為它不適用於函數。

pure real subroutine procA(arg1)
    implicit none
    integer :: arg1

    if (arg < 0) then
        return 1 ! exit the function and go to the first label supplied
                 ! when function was called. Also return 2, 3 etc.
    else
        procA = ... ! whatever it should do under normal circumstances
    endif
endsubroutine procA

.... 

! later on, procedure is called
num = procA(a, *220)

220 write(6,*) 'Error with func1: you've probably supplied a negative argument'

什么可能會更好的是eriktous建議 - 獲取程序返回狀態,可能作為邏輯值或整數,並讓程序每次調用該過程后檢查此值。 如果一切順利,繼續。 否則,請打印相關的錯誤消息。

歡迎評論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM