fortran - dinamica - Arrays de tamaño cero y verificación de límites de matriz
integer allocatable fortran (1)
No da ningún problema con el compilador fortran de Intel con -marques de comprobación; y el xlf de IBM, que en mi experiencia es extremadamente estricto, tampoco se quejó con -qcheck.
Pero en términos más generales, sí, no existe un estándar sobre lo que la verificación de límites debería o no debería hacer. Ciertamente puedo ver por qué algunos compiladores marcarían una asignación a una matriz de longitud cero como mala / incorrecta / extraña; es un extraño caso de esquina.
Cuando se compila con GNU Fortran (v4.4.3) o Sun Studio F95 (v8.3) y sin límites de matriz verificando que el siguiente programa se ejecute sin error. Sin embargo, cuando la verificación de límites de matriz está activada ( gfortran -fbounds-check
y f95 -C
, respectivamente) el ejecutable compilado de GNU se ejecuta nuevamente sin error, mientras que el ejecutable compilado Sun Studio da el error de tiempo de ejecución,
****** 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''
Eso es un error en la llamada a sub2()
, que utiliza un argumento ficticio automático de matriz para x
. Las llamadas a sub1()
se ejecutan bien con el compilador y cualquier indicador.
Que yo sepa este programa es "legal", en que una matriz de tamaño cero puede ser referenciada como una matriz de tamaño no cero, y no hay una indexación explícita de la dimensión de longitud cero de x
. ¿Pero hay algún tipo de corte de matriz de tamaño cero o sutileza de matriz automática que me falta aquí? ¿Y debería esperar que la comprobación de límites de matriz se comporte igual en diferentes compiladores, o debería considerar una extensión específica del proveedor?
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