所以我有一个程序,里面有这样的东西:
integer :: mgvn, stot, gutot, iprint, iwrit, ifail, iprnt
...
call readbh(lubnd,nbset,nchan,mgvn,stot,gutot,nstat,nbound,rr,bform,iprnt,iwrit,ifail)
然后在readbh
内:
CALL GETSET(LUBND,NSET,KEYBC,BFORM,IFAIL)
IF(IFAIL.NE.0) GO TO 99
...
99 WRITE(IWRITE,98) NBSET,LUBND
IFAIL = 1
RETURN
定义了所有其他变量,但ifail
不是。如果我在函数调用之前添加write(*,*) ifail
,我会得到未定义的变量错误,但是如果我把它留下来,它就不会抱怨,只是随函数逃跑,总是失败,{{1 }}
这是因为它只是到达IFAIL=1
函数中的参数的末尾,读取未初始化的内存 - 这只是随机的乱码 - 然后将这些位转换为readbh
- 这是除非我非常(非)幸运,并且几乎总是在制作int
ifail.ne.0
,否则不会为零?
答案 0 :(得分:1)
我会选择将您称为未定义变量的内容解释为未初始化的变量。一般而言,Fortran和许多其他编译的编程语言将很乐意使用未初始化的变量进行计算。它/它们是成年人的编程语言,如果你编程这种行为,它就是我们自己的头脑。编写使用未初始化变量的Fortran程序在语法上不正确,因此编译器不受语言标准的约束而引发警告或错误。
但是,Fortran确实具有编程函数和子例程的功能,以确保输出参数具有给定值。如果对过程中应该赋值的参数使用intent(out)
属性,那么编译器将检查是否进行了赋值,如果不是则会引发错误。
大多数编译器都可以选择使用未初始化的变量来运行运行时检查。例如,英特尔Fortran的标志为-check:uninit
。没有这个检查,是的,你的程序会将它在标记为ifail
的内存区域中找到的任何位模式解释为整数并继续。
您写道,您的功能始终以ifail == 1
失败。从您向我们展示的内容ifail
开始,就在return
之前(可能是)readbh
调用结束时,无条件设置为1
。
根据您对代码的揭示,它看起来好像ifail
旨在作为getset
的错误返回代码,因此在进入该子例程时未初始化它并不一定是错误的。但有点令人费解的是readbh
然后在返回之前将其设置为1
。