2012-08-02 115 views

回答

15

Fortran 90使用描述符來表示其數組的維度(形狀)並傳遞假定形狀的數組參數。 Fortran中的指針也很特殊 - 它們只能指向合格的目標。這使得Fortran中的調試器內省比C/C++更好。只需使用print arr(index)或其中一個info命令 - 無需花哨的東西。

示例代碼:

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 

編譯與調試信息,並與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, ... 

它不能顯示的假定大小的數組變量的原因很明顯的內容,但你可以打印每個元素單獨:

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

請注意,打印陣列因爲他們沒有被描述符和gdb通過運行陷入困境的部分不能在假定大小的數組參數工作:

(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

這真的很好,但不適合我,你的gdb/gfortran版本是什麼? (順便說一句,你的子程序foo在這個例子中缺少一個參數) – steabert 2012-08-03 13:02:41

+0

Scientific Linux 6.2(RHEL 6.2)上的'gfortran 4.4.6'(也用'4.7.0'測試過)和'gdb 7.2-50.e16'。你有編譯調試信息嗎? (修正了缺少的參數 - 指出它爲10x) – 2012-08-03 13:06:04

+1

謝謝,也許這是一個錯誤的種類,我不知道。我使用gfortran 4.7.1和gdb 7.4.1。如果我打印數組,我只是將'(0)'作爲輸出。 – steabert 2012-08-03 13:14:41

9

我碰到了類似的問題,發現thisthis鏈接有用。

它歸結爲:如果你沒有GDB和gfortran的正確版本,則需要例如

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

或做(對我來說)

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

到打印數組的第二個元素。你也可以做

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

看到數組元素2,...,2 + 5。

+0

''* (((datatype *)pointername)'符號有點混淆。 如果解除引用是使用'(dtype *)ptrname'完成一次 - 如何嵌套一次導致'*((dtype *)ptrname)'? – 2016-05-12 10:09:19

2

這適用於我在gdb 7.7.1:

print A(1)@N 

其中A是陣列,N是要被打印元件的數目。對於二維數組:

print A(1,1)@N 

我知道這是一個老問題,但谷歌查詢「廣發行打印Fortran數組」導致這裏。