调用子例程后变量奇怪地取零值

发布于 2024-11-13 02:33:07 字数 1768 浏览 3 评论 0原文

我在尝试将以前使用 compaq Visual Fortran 6.6 编译的代码转换为 gfortran 时遇到了一些问题。
这是我在使用 gfortran 时遇到的一个具体问题:
有一个名为“et”的变量,其值为 3E+10。然后程序调用子程序。 “et”没有出现在子程序中,但是返回主程序后它的值现在为0。
当用 compaq Visual fortran 编译时我没有遇到这个问题。
我正在处理的代码是一个巨大的科学程序,因此我只将其中的一小部分放在下面::

c
c     calculate load/unload modulus
c
500   t=(s1-s3)/2.
      aa=1.00
      if(iconeps.ne.1)bb=1.00
      if(smean.lt.ap1) smean=ap1
      if(xn.gt.0.000001) aa=(smean/atmp)**xn
      if(iconeps.eq.1)go to 220
      if(xm.gt.0.000001) bb=(smean/atmp)**xm
220   if(t.ge.0.99*sm1) go to 600
      et=xku*aa*atmp+tt*tm1
      if(iconeps.ne.1)bt=xkb*atmp*bb
      go to  900
600   et=(xkl*aa*atmp+tt*tm1)*(1.0-rf*sr)**2
      if(iconeps.ne.1)bt=xkb*atmp*bb
900   continue
      btmax=17.0*et
      btmin=0.33*et

      if(iconeps.ne.1)then
      tbt=(alf1+alf3*dtt)*dtt*(1.+vide)*tm2
      btf=bt+tbt
      bt=btf
      endif

      if(bt.lt.btmin) bt=btmin
      if(bt.gt.btmax) bt=btmax
      if(iconeps.eq.1)go to 1100

1000  continue

1050  if(mt.eq.mtyp4c)goto 1100
      s=0.0
      t=0.0
      call shap4n(s,t,f,pfs,pft)                           ! Modification by NHV
      call thick4n(s,t,xe,ye,thick)
      call bmat4n(xe,ye,f,pfs,pft,b,detj,thick)

c     calculate incremental strains

      do 1300 i=1,4
      temp=0.0
      do 1200 j=1,8
1200  temp=temp+b(i,j)*disp(j)
1300  depi(i)=temp
      epsv=0.0
      do 1400 i=1,2
1400  epsv=epsv+depi(i)
  epsv=epsv+depi(4)

      ev=vide-(1.+vide)*epsv

      if(ev.lt.0.0)ev=vide*.01

1100  continue

      call perm(permws,xkw,coef,rw,tvisc,ev,vide,tt,pp)

“et”保持良好的值,直到调用子例程“perm”之前。在此子例程之后,它的值为零。
“et”不在任何公共块中
这段代码是由几个不同的子例程调用的子例程的一部分。更奇怪的是,当在代码的其他部分调用它时我没有这个问题(“et”保持其值)
因此,如果有人曾经遇到过此类问题或对此有任何想法,我将非常感激

I have been facing some issues trying to convert a code previously compiled with compaq visual fortran 6.6 to gfortran.
Here is a specific problem I have met with gfortran :
There is a variable called "et" which takes the value 3E+10. Then the program calls a subroutine. "et" doesn't appear in the subroutine, but after coming back to the main program it has now the value 0.
When compliling with compaq visual fortran I didn't have this problem.
The code I am working on is a huge scientific program, so I put below only a small part of it :

c
c     calculate load/unload modulus
c
500   t=(s1-s3)/2.
      aa=1.00
      if(iconeps.ne.1)bb=1.00
      if(smean.lt.ap1) smean=ap1
      if(xn.gt.0.000001) aa=(smean/atmp)**xn
      if(iconeps.eq.1)go to 220
      if(xm.gt.0.000001) bb=(smean/atmp)**xm
220   if(t.ge.0.99*sm1) go to 600
      et=xku*aa*atmp+tt*tm1
      if(iconeps.ne.1)bt=xkb*atmp*bb
      go to  900
600   et=(xkl*aa*atmp+tt*tm1)*(1.0-rf*sr)**2
      if(iconeps.ne.1)bt=xkb*atmp*bb
900   continue
      btmax=17.0*et
      btmin=0.33*et

      if(iconeps.ne.1)then
      tbt=(alf1+alf3*dtt)*dtt*(1.+vide)*tm2
      btf=bt+tbt
      bt=btf
      endif

      if(bt.lt.btmin) bt=btmin
      if(bt.gt.btmax) bt=btmax
      if(iconeps.eq.1)go to 1100

1000  continue

1050  if(mt.eq.mtyp4c)goto 1100
      s=0.0
      t=0.0
      call shap4n(s,t,f,pfs,pft)                           ! Modification by NHV
      call thick4n(s,t,xe,ye,thick)
      call bmat4n(xe,ye,f,pfs,pft,b,detj,thick)

c     calculate incremental strains

      do 1300 i=1,4
      temp=0.0
      do 1200 j=1,8
1200  temp=temp+b(i,j)*disp(j)
1300  depi(i)=temp
      epsv=0.0
      do 1400 i=1,2
1400  epsv=epsv+depi(i)
  epsv=epsv+depi(4)

      ev=vide-(1.+vide)*epsv

      if(ev.lt.0.0)ev=vide*.01

1100  continue

      call perm(permws,xkw,coef,rw,tvisc,ev,vide,tt,pp)

: "et" keeps the good value until just before calling the subroutine "perm". Just after this subroutine it takes the value zero.
"et" isn't in any common block
This piece of code is part of a subroutine called by several different subroutines. What is even more strange is that when it is called in other parts of the code I doesn't have this problem ("et" keeps its value)
So if someone has ever met this kind of problem or have any idea about it I will be very gratefull

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

转身以后 2024-11-20 02:33:07

也许您遇到内存访问错误,例如数组边界违规,或者实际参数和虚拟参数之间不匹配。子例程的接口是否明确,例如从模块“使用”?还可以尝试打开编译器调试选项......显然是下标检查,但其他人可能会发现一些东西。 gfortran 4.5 或 4.6 的扩展集是:

-O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -std=f2008 -pedantic -fbacktrace

下标检查包含在 fcheck=all 中

Perhaps you have a memory access error, such as an array bounds violation, or a mismatch between actual and dummy arguments. Are the interfaces of the subroutines explicit, such as being "used" from a module? Also try turning on compiler debugging options ... obviously subscript checking, but others might catch something. An extensive set for gfortran 4.5 or 4.6 is:

-O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -std=f2008 -pedantic -fbacktrace

Subscript checking is included in fcheck=all

猫卆 2024-11-20 02:33:07

我遇到了这个问题。在我的主程序中,我使用双精度,但我在子程序中计算的数字是单精度。在我将它们更改为双倍后,它解决了问题,我得到了实际值而不是 0。

I had this problem. In my main program, I was using double precision but the numbers I calculated with in my subroutine were single precision. After I changed them to double it fixed the problem and I got actual values instead of 0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文