2012-08-02 8 views

Odpowiedz

15

Fortran 90 używa deskryptorów do reprezentowania wymiarów (kształtu) swoich tablic i do przekazywania argumentów tablicy o założonym kształcie. Również wskaźniki w Fortranie są specjalne - mogą wskazywać tylko na kwalifikowane cele. Pozwala to na znacznie lepszą introspekcję debuggera w Fortranie niż w C/C++. Wystarczy użyć polecenia print arr(index) lub jednego z poleceń info - bez potrzeby wymyślnych rzeczy.

Przykładowy kod:

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 

skompilować z informacji debugowania i uruchomić z 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, ... 

To nie może pokazać zawartość przyjęto wielkości argumentów tablicowych z oczywistych powodów, ale można wydrukować każdy element indywidualnie:

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

Należy zwrócić uwagę, że układ drukowania sekcje nie działa na przyjęto wielkości tablicy argumentów, gdyż nie są przekazywane przez deskryptor i gdb tras w kłopoty:

(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

To naprawdę miłe, ale nie działa dla mnie, jaka jest twoja wersja gdb/gfortran? (btw, twój podprogram foo nie ma argumentu w tym przykładzie) – steabert

+0

'gfortran 4.4.6' (również testowany z' 4.7.0') i 'gdb 7.2-50.e16' na Scientific Linux 6.2 (RHEL 6.2). Czy skompilowałeś informacje debugowania? (naprawiono brakujący argument - 10x za wskazanie) –

+1

dzięki, może to jakiś błąd, nie wiem. Używam gfortran 4.7.1 i gdb 7.4.1. Po prostu wypisuję '(0)' jako wynik, jeśli wydrukuję tablice. – steabert

9

natknąłem się na podobny problem i okazało this i this odnośnik pożytecznego.

To sprowadza się do: jeśli nie masz odpowiednie wersje gdb i gfortran, trzeba zrobić na przykład

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

lub (w moim przypadku)

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

do wydrukuj drugi element tablicy. Możesz także wykonać , aby zobaczyć elementy tablicy 2, ..., 2 + 5.

+0

'' ((datatype *) pointername) 'notacja jest nieco myląca. jeśli dereferencje zostały wykonane jednokrotnie z '(dtype *) ptrname' - jak zagnieżdżanie może prowadzić do' * ((dtype *) ptrname) ?? –

2

Działa mi GDB 7.7.1:

print A(1)@N 

, gdzie A oznacza macierz, a N oznacza liczbę elementów przeznaczonych do druku. W przypadku tablicy dwuwymiarowej:

print A(1,1)@N 

Wiem, że jest to stare pytanie, ale zapytanie Google "gdb print fortran array" prowadzi tutaj.