回 帖 发 新 帖 刷新版面

主题:[讨论]语句函数对数组赋值出现的一个很奇怪的问题

程序:
 PROGRAM assign_inlinefun2mat
   !
   implicit none
   !
   real,dimension(3) :: m = (/0.2,0.4,0.6/),v
   real :: r
   integer :: i
   !
   !线性内插
   real :: a0,a1,position,interp
   interp(a0,a1,position) = a0*(1.0-position)+a1*position 
   !
   !直接赋值
   v = 0.0
   print*,'----part1----'
   do i = 1,3
     print*,'----start----'
     print*,'v=',v
     print*,'interp(0,1,m(i))=',interp(0,1,m(i))
     v = interp(0,1,m(i))
     print*,'----assign----'
     print*,'v=',v
      print*,'interp(0,1,m(i))=',interp(0,1,m(i))
   end do
   !
   !通过变量间接赋值
   v = 0.0
   print*,'----part2----'
   do i = 1,3
     print*,'----start----'
     print*,'v=',v
     print*,'interp(0,1,m(i))=',interp(0,1,m(i))
     r = interp(0,1,m(i))
     v=r
     print*,'----assign----'
     print*,'v=',v
     print*,'interp(0,1,m(i))=',interp(0,1,m(i))
   end do
   !
 END PROGRAM assign_inlinefun2mat

windows下 CVF 6.5的结果:
[color=FF0000] ----part1----
 ----start----
 v=  0.0000000E+00  0.0000000E+00  0.0000000E+00
 interp(0,1,m(i))=  0.2000000    
 ----assign----
 v=  0.0000000E+00  0.0000000E+00  0.0000000E+00
 interp(0,1,m(i))=  0.2000000    
 ----start----
 v=  0.0000000E+00  0.0000000E+00  0.0000000E+00
 interp(0,1,m(i))=  0.4000000    
 ----assign----
 v=  0.2000000      0.2000000      0.2000000    
 interp(0,1,m(i))=  0.4000000    
 ----start----
 v=  0.2000000      0.2000000      0.2000000    
 interp(0,1,m(i))=  0.6000000    
 ----assign----
 v=  0.4000000      0.4000000      0.4000000    
 interp(0,1,m(i))=  0.6000000    [/color]
 ----part2----
 ----start----
 v=  0.4000000      0.4000000      0.4000000    
 interp(0,1,m(i))=  0.2000000    
 ----assign----
 v=  0.2000000      0.2000000      0.2000000    
 ----start----
 v=  0.2000000      0.2000000      0.2000000    
 interp(0,1,m(i))=  0.4000000    
 ----assign----
 v=  0.4000000      0.4000000      0.4000000    
 ----start----
 v=  0.4000000      0.4000000      0.4000000    
 interp(0,1,m(i))=  0.6000000    
 ----assign----
 v=  0.6000000      0.6000000      0.6000000    

linux下ifort 11.0的结果:
 ----part1----
 ----start----
 v=  0.0000000E+00  0.0000000E+00  0.0000000E+00
 interp(0,1,m(i))=  0.2000000    
 ----assign----
 v=  0.2000000      0.2000000      0.2000000    
 interp(0,1,m(i))=  0.2000000    
 ----start----
 v=  0.2000000      0.2000000      0.2000000    
 interp(0,1,m(i))=  0.4000000    
 ----assign----
 v=  0.4000000      0.4000000      0.4000000    
 interp(0,1,m(i))=  0.4000000    
 ----start----
 v=  0.4000000      0.4000000      0.4000000    
 interp(0,1,m(i))=  0.6000000    
 ----assign----
 v=  0.6000000      0.6000000      0.6000000    
 interp(0,1,m(i))=  0.6000000    
 ----part2----
 ----start----
 v=  0.0000000E+00  0.0000000E+00  0.0000000E+00
 interp(0,1,m(i))=  0.2000000    
 ----assign----
 v=  0.2000000      0.2000000      0.2000000    
 interp(0,1,m(i))=  0.2000000    
 ----start----
 v=  0.2000000      0.2000000      0.2000000    
 interp(0,1,m(i))=  0.4000000    
 ----assign----
 v=  0.4000000      0.4000000      0.4000000    
 interp(0,1,m(i))=  0.4000000    
 ----start----
 v=  0.4000000      0.4000000      0.4000000    
 interp(0,1,m(i))=  0.6000000    
 ----assign----
 v=  0.6000000      0.6000000      0.6000000    
 interp(0,1,m(i))=  0.6000000    


在CVF里直接用语句函数对数组赋值,得到的实际上是上一个循环的结果(结果里红色的部分),如果先把语句函数的结果赋给一个变量,再将该变量赋给数组就没有这个问题,ifort里则不管怎么赋值都没有问题。
本来这样赋值应该算一种错误,不过这个结果实在有些诡异,冒昧的发上来,请各位高手分析下为什么会得到的是上一个循环的值。

回复列表 (共23个回复)

21 楼

[quote][quote]statement function 类型不匹配不报错的吗? 难道是一个宏, 只代入不检查属性? 我觉得这可能是一个bug.
楼主的问题恐怕要懂反汇编的朋友查查什么原因. 也可能是个bug.[/quote]

类型不匹配恐怕不是主要问题,我改成interp(0.,1.,m(i)) 一样出错。

我试了一下,将v = interp(0.,1.,m(i))改成
do j=1,3
    v(j) = interp(0.,1.,m(i))
end do
CVF Compiler就没问题了,看来直接给数组每个元素赋值这种写法,对语句函数不可用。
不过我也不太清楚为什么,呵呵。[/quote]

我前面也说过, 我改成0.0, 1.0问题依然存在. 而楼主给的问题只是cvf出错更多似是bug, 如果是bug就难以在代码上找到原因. 不如请雪球来反汇编看看.

[color=FF0000]我在强调的是楼主问题之外的顾虑. 连ivf也没有对类型进行检查, 以后再用statement function 你会放心吗?(我现在不方便做ivf测试, 是楼主讲的, 楼主方便的话贴上ivf的版本信息) [/color]
我勉强在cvf在再做如下测试一下. 我把输入的1改成[color=FF0000]'l'[/color]字母.

   do i = 1,3
     print*,'----start----'
     print*,'v=',v
     print*,'interp(0,1,m(i))=',interp(0,'l',m(i))
     v = interp(0,'l',m(i))
     print*,'----assign----'
     print*,'v=',v
      print*,'interp(0,1,m(i))=',interp(0,'l',m(i))
   end do
   !
   !通过变量间接赋值
   v = 0.0
   print*,'----part2----'
   do i = 1,3
     print*,'----start----'
     print*,'v=',v
     print*,'interp(0,1,m(i))=',interp(0,'l',m(i))
     r = interp(0,'l',m(i))
     v=r
     print*,'----assign----'
     print*,'v=',v
     print*,'interp(0,1,m(i))=',interp(0,'l',m(i))
   end do


 ----part1----
 ----start----
 v=  0.0000000E+00  0.0000000E+00  0.0000000E+00
 interp(0,1,m(i))=  2.7126509E-20
 ----assign----
 v=  0.0000000E+00  0.0000000E+00  0.0000000E+00
 interp(0,1,m(i))=  2.7126509E-20
 ----start----
 v=  0.0000000E+00  0.0000000E+00  0.0000000E+00
 interp(0,1,m(i))=  5.4253019E-20
 ----assign----
 v=  2.7126509E-20  2.7126509E-20  2.7126509E-20
 interp(0,1,m(i))=  5.4253019E-20
 ----start----
 v=  2.7126509E-20  2.7126509E-20  2.7126509E-20
 interp(0,1,m(i))=  8.1379534E-20
 ----assign----
 v=  5.4253019E-20  5.4253019E-20  5.4253019E-20
 interp(0,1,m(i))=  8.1379534E-20
 ----part2----
 ----start----
 v=  0.0000000E+00  0.0000000E+00  0.0000000E+00
 interp(0,1,m(i))=  2.7126509E-20
 ----assign----
 v=  2.7126509E-20  2.7126509E-20  2.7126509E-20
 interp(0,1,m(i))=  2.7126509E-20
 ----start----
 v=  2.7126509E-20  2.7126509E-20  2.7126509E-20
 interp(0,1,m(i))=  5.4253019E-20
 ----assign----
 v=  5.4253019E-20  5.4253019E-20  5.4253019E-20
 interp(0,1,m(i))=  5.4253019E-20
 ----start----
 v=  5.4253019E-20  5.4253019E-20  5.4253019E-20
 interp(0,1,m(i))=  8.1379534E-20
 ----assign----
 v=  8.1379534E-20  8.1379534E-20  8.1379534E-20
 interp(0,1,m(i))=  8.1379534E-20
Press any key to continue

[color=FF0000]cvf下依然没有报错. 不知道ivf有没有报错[/color]

[color=FF0000]-----------------------------------------------------
-----------------------------------------------------[/color]

我用楼主的源码在gfortran下编译了一下.

C:\testpro>gfortran temp.f90
temp.f90:19.39:

     print*,'interp(0,1,m(i))=',interp(0,1,m(i))
                                       1
Error: Type mismatch in argument 'a0' at (1); passed INTEGER(4) to REAL(4)
temp.f90:20.16:

     v = interp(0,1,m(i))
                1
Error: Type mismatch in argument 'a0' at (1); passed INTEGER(4) to REAL(4)
temp.f90:23.40:

      print*,'interp(0,1,m(i))=',interp(0,1,m(i))
                                        1
Error: Type mismatch in argument 'a0' at (1); passed INTEGER(4) to REAL(4)
temp.f90:32.39:

     print*,'interp(0,1,m(i))=',interp(0,1,m(i))
                                       1
Error: Type mismatch in argument 'a0' at (1); passed INTEGER(4) to REAL(4)
temp.f90:33.16:

     r = interp(0,1,m(i))
                1
Error: Type mismatch in argument 'a0' at (1); passed INTEGER(4) to REAL(4)
temp.f90:37.39:

     print*,'interp(0,1,m(i))=',interp(0,1,m(i))
                                       1
Error: Type mismatch in argument 'a0' at (1); passed INTEGER(4) to REAL(4)

C:\testpro>

环境是dongyunxun兄编译gcc for windows, MinGW_gcc4.5.1
有ivf环境的朋友测试一下新版本的ivf在debug模式下是否没有报错?

22 楼

ifort -v
Version 11.0

ifort我不是很熟,不知道有没有调整编译时检查错误等级的选项,只是简单的编译连接了一下
ifort -g -c assign_inlinefun2mat.f90
ifort assign_inlinefun2mat.o -g -o assign

CVF里类型不匹配不报错确实是个隐患,不过这种检查同样是依赖于编译器的,跟statement function本身的语法无关

23 楼


除了bug之外,还没有人能给出合理的解释么?

我来回复

您尚未登录,请登录后再回复。点此登录或注册