2012-08-02 110 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数组”导致这里。