2011-04-12 35 views
4

使用GNU Fortran(v4.4.3)或Sun Studio F95(v8.3)进行编译时,并且没有数组边界检查以下程序运行没有错误。然而,当数组边界检查上(gfortran -fbounds-checkf95 -C,分别)切换GNU编译的可执行文件再次运行没有错误,而太阳录音室编译的可执行文件给出了运行时错误,零大小阵列和数组边界检查

****** FORTRAN RUN-TIME SYSTEM ****** 
Subscript out of range. Location: line 44 column 20 of 'nosize.f90' 
Subscript number 2 has value 1 in array 't$27' 

这是一个错误的调用sub2(),该函数使用x的自动数组伪参数。 sub1()调用与编译器和任何标志都可以正常运行。

据我所知,这个程序是“合法的”,因为零大小的数组可能被引用为非零大小的数组,并且没有明确索引x的零长度维数。但是有没有一些零大小的数组切片或自动数组微妙,我在这里失踪?我应该期望数组边界检查在不同的编译器中表现相同,还是应该将其视为特定于供应商的扩展?

MODULE subs 
    IMPLICIT NONE 
CONTAINS  
    SUBROUTINE sub1(x) 
    IMPLICIT NONE 
    REAL :: x(:,:) 
    PRINT*,'------------------------------------' 
    PRINT*,SHAPE(x) 
    PRINT*,SIZE(x) 
    END SUBROUTINE sub1 

    SUBROUTINE sub2(n1,n3,x) 
    IMPLICIT NONE 
    INTEGER,INTENT(in) :: n1, n3 
    REAL :: x(n1,n3) 
    PRINT*,'------------------------------------' 
    PRINT*,SHAPE(x) 
    PRINT*,SIZE(x) 
    END SUBROUTINE sub2 
END MODULE subs 


PROGRAM nosize 
    USE subs 
    IMPLICIT NONE  
    INTEGER :: n1 = 2, n2 = 2, n3 = 0 
    REAL,ALLOCATABLE :: x(:,:,:) 

    ALLOCATE(x(n1,n2,n3)) 
    x(:,:,:) = -99.9 

    PRINT*,'ALLOCATED? ',ALLOCATED(x) 
    PRINT*,'SHAPE =',SHAPE(x) 
    PRINT*,'SIZE =',SIZE(x) 
    PRINT*,'X  =',x 

    CALL sub1(x(:,1,:)) 
    CALL sub2(n1,n3,x(:,1,:)) 

END PROGRAM nosize 

回答

3

它不会给intel fortran编译器带来任何问题,而且带有-check bounds;和IBM的xlf,在我的经验中非常严格,也没有用-qcheck抱怨。

但更广泛地说,是的,关于边界检查应该或不应该做什么没有标准。我当然可以看到为什么一些编译器标记为一个零长度数组的赋值为坏/错/奇怪;这是一个奇怪的角落案例。

+2

是的,这就是我所怀疑的,Sun有突出的表现。哦,这只是说明我需要说服代码拥有者将许多子程序包装在模块中,而不是继续使用标准遵从之剑。 – Deditos 2011-04-12 20:42:46