2012-08-02 17 views

risposta

15

Fortran 90 utilizza descrittori per rappresentare le dimensioni (la forma) dei suoi array e per passare argomenti di matrice di forma presunta. Anche i puntatori in Fortran sono speciali: possono solo indicare obiettivi qualificati. Ciò consente un'introspezione del debugger molto migliore in Fortran rispetto a C/C++. Basta usare print arr(index) o uno dei comandi info - non c'è bisogno di cose fantasiose.

codice di esempio:

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 

Compilare con le informazioni di debug e gestito 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, ... 

Non può mostrare il contenuto di assumed-size gli argomenti di matrice per ovvie ragioni, ma è possibile stampare ogni elemento singolarmente:

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

Nota che matrice di stampa sezioni non funziona su assunto dimensioni argomenti di matrice in quanto non sono passati per descrittore e gdb corse nei guai:

(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

Questo è davvero bello, ma non funziona per me, qual è la versione di gdb/gfortran? (btw, la subroutine foo manca un argomento nell'esempio) – steabert

+0

'gfortran 4.4.6' (anche testato con' 4.7.0') e 'gdb 7.2-50.e16' su Scientific Linux 6.2 (RHEL 6.2). Hai compilato con le informazioni di debug? (corretto l'argomento mancante - 10x per indicarlo) –

+1

grazie, forse è un insetto di sorta, non lo so. Uso gfortran 4.7.1 e gdb 7.4.1. Ho appena ottenuto '(0)' come output se stampo gli array. – steabert

9

mi sono imbattuto in un problema simile e ha trovato this e this link utile.

si riduce a: se non si hanno le versioni corrette di gdb e gfortran, è necessario fare per esempio

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

o (nel mio caso)

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

a stampa il 2 ° elemento dell'array. Puoi anche fare

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

per vedere gli elementi dell'array 2, ..., 2 + 5.

+0

the' * ((datatype *) pointername) 'la notazione è leggermente confusa. se il dereferenziazione viene eseguito una volta con '(dtype *) ptrname' - come può nidificare una volta portare a' * ((dtype *) ptrname) '?? –

2

Questo funziona per me in gdb 7.7.1:

print A(1)@N 

dove A è la matrice e N è il numero di elementi da stampare. Per un array bidimensionale:

print A(1,1)@N 

So che questa è una vecchia questione, ma di query Google "gdb stampa di matrice FORTRAN" porta qui.

Problemi correlati