2012-08-02 29 views

Respuesta

15

Fortran 90 utiliza descriptores para representar las dimensiones (la forma) de sus arrays y para pasar argumentos de matriz con forma asumida. También los indicadores en Fortran son especiales; solo pueden señalar objetivos calificados. Esto permite una introspección del depurador mucho mejor en Fortran que en C/C++. Solo use print arr(index) o uno de los comandos info, sin necesidad de materiales sofisticados.

Código de ejemplo:

program arr 
    real, dimension(40) :: stack_array 
    real, allocatable, dimension(:), target :: heap_array 
    real, dimension(:), pointer :: ptr_array 
    integer :: i 
    ! Interface required because of the assumed-shape array argument 
    interface 
    subroutine foo(bar, baz, qux, ptr) 
     real, dimension(:) :: bar 
     real, dimension(40) :: baz 
     real, dimension(*) :: qux 
     real, dimension(:), pointer :: ptr 
    end subroutine foo 
    end interface 

    allocate(heap_array(40)) 

    forall(i = 1:40) stack_array(i) = i 
    heap_array = stack_array + 2 
    ptr_array => heap_array 

    print *, stack_array(1) 

    call foo(stack_array, stack_array, stack_array, ptr_array) 

    deallocate(heap_array) 
end program arr 

subroutine foo(bar, baz, qux, ptr) 
    real, dimension(:) :: bar 
    real, dimension(40) :: baz 
    real, dimension(*) :: qux 
    real, dimension(:), pointer :: ptr 

    print *, bar(1), baz(1), qux(1), ptr(1) 
end subroutine foo 

Compilar con información de depuración y correr con gdb:

$ gfortran -g -o arr.x arr.f90 && gdb ./arr.x 
... 
(gdb) info locals 
heap_array = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ... 
ptr_array = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ... 
stack_array = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ... 
(gdb) print heap_array 
$1 = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ... 
(gdb) print ptr_array(3:7) 
$2 = (5, 6, 7, 8, 9) 
... 
(gdb) info args 
bar = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ... 
baz = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ... 
qux =() 
ptr = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ... 

no puede mostrar el contenido de los argumentos de matriz de tamaño asumido por razones obvias, pero se puede imprimir cada elemento individualmente:

(gdb) print qux(1) 
$5 = 1 
(gdb) print qux(2) 
$6 = 2 
(gdb) print qux(15) 
$7 = 15 

Tenga en cuenta que la matriz de impresión secciones no funciona en argumentos matriz de tamaño asumido ya que no se pasan por descriptor y gdb se mete en problemas:

(gdb) print qux(1:8) 
$8 = (0, 0, 0, 0, 0, 0, 2.25609053e-43, 0) 
(gdb) print qux(2:9) 
$9 = (0, 0, 0, 0, 0, 0, 2.25609053e-43, 0) 
+0

Eso es muy bonito, pero no funciona para mí, lo que es su GDB/versión gfortran? (Por cierto, su foo subrutina es que falta un argumento en el ejemplo) – steabert

+0

'gfortran 4.4.6' (también probó con' 4.7.0') y 'gdb 7.2-50.e16' en Scientific Linux 6.2 (RHEL 6.2). ¿Compiló con información de depuración? (corrigió el argumento que faltaba - 10x para señalarlo) –

+1

gracias, tal vez es una especie de error, no sé. Yo uso gfortran 4.7.1 y gdb 7.4.1. Acabo de obtener '(0)' como salida si imprimo las matrices. – steabert

9

me encontré con un problema similar y encontré this y this vínculo útil.

que se reduce a: si no tiene las versiones correctas de GDB y gfortran, que tiene que hacer, por ejemplo,

(gdb) print *((real *)my_array + 2) 

o (en mi caso)

(gdb) print *((real *)my_array + 2) 

a imprime el segundo elemento de la matriz. También puede hacer

(gdb) print *((real_8 *)my_array + 2)@5 

ver los elementos 2, ..., 2 + 5 de la matriz.

+0

el '* La notación ((datatype *) pointername) 'es un poco confusa. si la desreferenciación se hace una vez con '(dtype *) ptrname' - ¿cómo puede anidar una vez llevar a' * ((dtype *) ptrname) '?? –

2

Esto funciona para mí en gdb 7.7.1:

print A(1)@N 

donde A es la matriz y N es el número de elementos que va a imprimirse. Para una matriz de dos dimensiones:

print A(1,1)@N 

Sé que esto es una cuestión de edad, pero consulta Google "GDB de impresión matriz FORTRAN" conduce aquí.