Fortran语法中的缺陷和陷阱

您所在的位置:网站首页 kindof和akindof Fortran语法中的缺陷和陷阱

Fortran语法中的缺陷和陷阱

#Fortran语法中的缺陷和陷阱| 来源: 网络整理| 查看: 265

简介

Fortran大量的用于数值计算,但是由于其年代久远,随着标准不断变化,编译器不断升级,有些古老的特性并没有被移除,导致初学者经常踩坑。在此总结一些常见的盲点。

变量定义在大部分书籍中,都会使用real*8,complex*8 这样的定义,但是实际上,这种定义方式属于编译器扩展,并不是标准的一部分real*8::a (GNU Fortran)Error: GNU Extension: Nonstandard type declaration REAL*8 at (Ifort) warning #6916: Fortran 2018 does not allow this length specification. [8]

而且, complex*8 对应的其实是 complex(4) , complex*16 对应的其实是 complex(8)

在使用一些古老的程序,或者看一些文档(比如Lapack文档)的时候,经常容易混淆

·子程序内部变量的默认save 属性

program main implicit none call test() call test() call test() contains subroutine test() integer::a=1 a=a+1 write(*,*)a end subroutine end program main !> 2 3 4

此时变量a会具有save属性,也就是说,a=1这个语句只会在第一次调用的时候执行。变量会保留上一次执行的值。考虑到兼容老代码的原因,这个特性并没有被移除。

变量赋值复数变量的赋值 如果是常数,可以使用a=(1.0,2.0)来赋值,如果有变量就需要一个转换函数a=cmplx(x,y),但是,此处cmplx默认返回的是一个complex(4),即使输入的x,y都是real(8),这时候需要a=cmplx(x,y,kind=8)给定kind属性 可分配数组的重分配 这个算一个特性,但是可能会造成一些bug, 如果数组定义为可分配的,那么如果直接使用变量名赋值,则如果数组的大小不一致,可分配数组就会重新分配。小代码中,你可以用它完成一些数组追加的工作。program main implicit none integer,allocatable::a(:) a=[1] write(*,*)a a=[1,2] write(*,*)a a=[a,3,4,5] write(*,*)a end program main !> 1 1 2 1 2 3 4 5参数传递在一些老代码中,会经常出现参数不匹配的情况,比如real(4)->real(8),这些代码可以正常编译,由于Fortran是传地址的,所以就会按照内存顺序,重新解析,可能偏离了本来的意图。现代的编译器会检查这些不匹配的情况,并报错。老代码中的数组传递方式,缺少必要的接口检查一些避免错误的方法编译选项 善于使用gfortran中的-fcheck=all 和ifort中的-check all 选项 使用module 多多使用module, module 中的函数会有显式的接口,在编译阶段就可以给出代码可能存在的一些错误


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3