使用 gfortran 编译器在 Fortran 代码中意外重新分配整数变量
Unintentional re-assignment of integer variable in Fortran code using gfortran compiler
我有一个整数变量(隐式声明为 INTEGER*4),它在整个循环结构中的某一点意外地从 51 更改为 -1074038743。我已经确认它只分配在我打算分配的地方。
我已将 WRITE 语句放置在几个重要位置,此后我仍然不清楚为什么要更改它。它(在最内层循环的一次迭代中)从一段代码更改为另一段代码,其中所讨论的变量仅作为 DO 循环的边界涉及。我已经验证该程序在连续 compilations/runs 上以相同的方式运行异常。 [编辑] 这只是一些概述整个程序结构的伪代码。
DO 13 I = 1, NUM1
DO 40 J = 1, NUM2
NV = 51
.... some code
WRITE(*,*) NV
.... some code
WRITE(*,*) NV
.... some code
WRITE(*,*) NV
40 CONTINUE
13 CONTINUE
在第三个 WRITE 语句中该值已损坏。这发生在节目 运行 大约 16 分钟后(大约 10% 的时间)。
这是上面第二个和第三个WRITE语句之间的相关代码。
DO 167 I8 = JNPR, INPR
WRITE(*,*)"in i8 loop,i8, NV= ", i8, NV
R12S = 0
ROVS = 0
STORE(M0) = E(I8)
M0 = M0 + 1
numb = inpr - jnpr + 1
WRITE(*,'(8/,A,i4,A,i4,A,8/)')'..on ',jvcnt,'of',numb,'cases..'
jvcnt = jvcnt + 1
WRITE(*,*)"HERE 21",NLS(I8,1),NLS(I8,2),I8
EB=E(NLS(I8,1))+E(i8)
WRITE(*,*)"HERE 22"
EA=E(NLS(I8,2))+E(i8)
E1=QABS(EB-EDALL)
E2=QABS(EA-EDALL)
W(1)=1/E1
W(2)=1/E2
W12=W(1)+W(2)
WP(1)=W(1)/W12
WP(2)=W(2)/W12
WP22=WP(2)**2
WP12=WP(1)**2
ED=QABS((WP(1)*E(NLS(I8,1))+WP(2)*E(NLS(I8,2)))-E(I8))
G1=NLS(i8,1)
G2=NLS(i8,2)
WRITE(17,988) "i8",i8,"EB",EB,"EA",EA,"E1",E1,"E2",E2,"W(1)",W(1)
1 ,"W(2)",W(2),"w12",w12,"WP(1)",WP(1),"E(NLS(I8,1))",G1,
1 "E(NLS(i8,2))",G2,"ED",ED
988 format(1x,a,i3,11(A,D26.19,/))
DO 169 I9 = 1,2
WRITE(*,*)"in i9 loop,i9, NV= ", i9, NV`
我不确定如何获得可重现的示例(当我尝试解决问题时并没有真正发生)。它似乎发生在我的代码的上下文中(大约 6000 行长),但我已经验证了所讨论的整数变量从未被重新分配,所以我希望有人能对可能导致的原因有所了解这个。
我收到分段错误通知,因为 NV 被用作索引,但我自己对此进行的故障排除告诉我 NV 本身就是如上所述的问题。
代码片段可能不够,无法找到错误。
在这些情况下我的做法:编译程序:
gfortran -O0 -g -Wall -pedantic -fcheck=all
并更改代码,直到所有 compile-warnings 和 run-time 错误都消失。
如果程序仍然运行不正常:安装 valgrind,运行 valgrind 下的程序如下:
valgrind ./a.out
并分析 valgrind 的输出。这对我帮助很大。
我有一个整数变量(隐式声明为 INTEGER*4),它在整个循环结构中的某一点意外地从 51 更改为 -1074038743。我已经确认它只分配在我打算分配的地方。
我已将 WRITE 语句放置在几个重要位置,此后我仍然不清楚为什么要更改它。它(在最内层循环的一次迭代中)从一段代码更改为另一段代码,其中所讨论的变量仅作为 DO 循环的边界涉及。我已经验证该程序在连续 compilations/runs 上以相同的方式运行异常。 [编辑] 这只是一些概述整个程序结构的伪代码。
DO 13 I = 1, NUM1
DO 40 J = 1, NUM2
NV = 51
.... some code
WRITE(*,*) NV
.... some code
WRITE(*,*) NV
.... some code
WRITE(*,*) NV
40 CONTINUE
13 CONTINUE
在第三个 WRITE 语句中该值已损坏。这发生在节目 运行 大约 16 分钟后(大约 10% 的时间)。 这是上面第二个和第三个WRITE语句之间的相关代码。
DO 167 I8 = JNPR, INPR
WRITE(*,*)"in i8 loop,i8, NV= ", i8, NV
R12S = 0
ROVS = 0
STORE(M0) = E(I8)
M0 = M0 + 1
numb = inpr - jnpr + 1
WRITE(*,'(8/,A,i4,A,i4,A,8/)')'..on ',jvcnt,'of',numb,'cases..'
jvcnt = jvcnt + 1
WRITE(*,*)"HERE 21",NLS(I8,1),NLS(I8,2),I8
EB=E(NLS(I8,1))+E(i8)
WRITE(*,*)"HERE 22"
EA=E(NLS(I8,2))+E(i8)
E1=QABS(EB-EDALL)
E2=QABS(EA-EDALL)
W(1)=1/E1
W(2)=1/E2
W12=W(1)+W(2)
WP(1)=W(1)/W12
WP(2)=W(2)/W12
WP22=WP(2)**2
WP12=WP(1)**2
ED=QABS((WP(1)*E(NLS(I8,1))+WP(2)*E(NLS(I8,2)))-E(I8))
G1=NLS(i8,1)
G2=NLS(i8,2)
WRITE(17,988) "i8",i8,"EB",EB,"EA",EA,"E1",E1,"E2",E2,"W(1)",W(1)
1 ,"W(2)",W(2),"w12",w12,"WP(1)",WP(1),"E(NLS(I8,1))",G1,
1 "E(NLS(i8,2))",G2,"ED",ED
988 format(1x,a,i3,11(A,D26.19,/))
DO 169 I9 = 1,2
WRITE(*,*)"in i9 loop,i9, NV= ", i9, NV`
我不确定如何获得可重现的示例(当我尝试解决问题时并没有真正发生)。它似乎发生在我的代码的上下文中(大约 6000 行长),但我已经验证了所讨论的整数变量从未被重新分配,所以我希望有人能对可能导致的原因有所了解这个。
我收到分段错误通知,因为 NV 被用作索引,但我自己对此进行的故障排除告诉我 NV 本身就是如上所述的问题。
代码片段可能不够,无法找到错误。
在这些情况下我的做法:编译程序:
gfortran -O0 -g -Wall -pedantic -fcheck=all
并更改代码,直到所有 compile-warnings 和 run-time 错误都消失。
如果程序仍然运行不正常:安装 valgrind,运行 valgrind 下的程序如下:
valgrind ./a.out
并分析 valgrind 的输出。这对我帮助很大。