Fortran 标准和内在程序标准

 2022-01-07 

Fortran standard and intrinsic procedure standard

在 GNU Fortran 编译器的文档中,对于特定的内在函数,有一个标准。例如,CPU_TIME 是一个内在过程,表明其标准是 Fortran 95 及更高版本。我的问题是关于this的含义。

我理解 Fortran 标准就像一组规则,您的代码被定义为符合标准(Fortran 77、90、95、2003 或 2008)。这是否意味着 CPU_TIME 只能与 Fortran 95 一起使用?实际上,我已经知道答案了,我可以在带有 .f 扩展名的 Fortran 77 文件中使用 CPU_TIME 而无需编译器抱怨,使用 Gfortran 版本 > 5 进行编译。这是因为编译器能够处理遇到的任何标准吗?在代码中?我知道 -std 标志,但我如何确定例如 Fortran 77 代码仅使用 Fortran 77 的内在过程?


简短的回答,您无法使用 gnu 编译器区分 f95 以下的标准。从 f95 及更高版本,您可以使用选项 -std 强制编译器将上述标准的功能视为错误。

长答案:

gnu 编译器的文档是这样说的:

-std=std
Specify the standard to which the program is expected to conform, which may be one of a€?f95a€?, a€?f2003a€?, a€?f2008a€?, a€?gnua€?, or a€?legacya€?. The
default value for std is a€?gnua€?, which specifies a superset of the
Fortran 95 standard that includes all of the extensions supported by
GNU Fortran, although warnings will be given for obsolete extensions
not recommended for use in new code. The a€?legacya€? value is equivalent
but without the warnings for obsolete extensions, and may be useful
for old non-standard programs. The a€?f95a€?, a€?f2003a€? and a€?f2008a€? values
specify strict conformance to the Fortran 95, Fortran 2003 and Fortran
2008 standards, respectively; errors are given for all extensions
beyond the relevant language standard, and warnings are given for the
Fortran 77 features that are permitted but obsolescent in later
standards. a€?-std=f2008tsa€? allows the Fortran 2008 standard including
the additions of the Technical Specification (TS) 29113 on Further
Interoperability of Fortran with C and TS 18508 on Additional Parallel
Features in Fortran.

1
2
3
4
- `-std=f95` will consider features above f95 as errors
- `-std=f2003` will consider features above f2003 as errors
- `-std=f2008` will consider features above f2008 as errors
- etc.

您可能需要检查其他编译器。

简单验证:编译以下程序(由 Fortran wiki 提供),使用和不使用 -std=f95 选项,看看会发生什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module class_Circle
    implicit none
    private
    real :: pi = 3.1415926535897931d0 ! Class-wide private constant

    type, public :: Circle
        real :: radius
    contains
        procedure :: area => circle_area
        procedure :: print => circle_print
    end type Circle
contains
    function circle_area(this) result(area)
        class(Circle), intent(in) :: this
        real :: area
        area = pi * this%radius**2
    end function circle_area

    subroutine circle_print(this)
        class(Circle), intent(in) :: this
        real :: area
        area = this%area()  ! Call the type-bound function
        print *, 'Circle: r = ', this%radius, ' area = ', area
    end subroutine circle_print
end module class_Circle


program circle_test
    use class_Circle
    implicit none

    type(Circle) :: c     ! Declare a variable of type Circle.
    c = Circle(1.5)       ! Use the implicit constructor, radius = 1.5.
    call c%print          ! Call the type-bound subroutine
end program circle_test