如何在GDB中打印Fortran数组?

15
在C/C++中,如果我想将一个指针打印成数组,通常会使用name@dimension的格式。那么在Fortran中,该怎么做才能实现类似的效果呢?
3个回答

16

Fortran 90使用描述符来表示其数组的维度(即形状)并传递假设形状的数组参数。此外Fortran中的指针是特殊的,它们只能指向受限目标。这比C/C++在Fortran中允许更好的调试器内省。只需使用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)

那真的很好,但对我没有用,你的 gdb/gfortran 版本是多少?(顺便说一下,在示例中你的子程序 foo 缺少一个参数) - steabert
gfortran 4.4.6(也测试过4.7.0)和gdb 7.2-50.e16在Scientific Linux 6.2(RHEL 6.2)上。您是否使用调试信息进行编译?(修复了缺少的参数 - 感谢指出) - Hristo Iliev
1
谢谢,也许这是某种错误,我不知道。我使用的是gfortran 4.7.1和gdb 7.4.1。如果我打印数组,我只会得到(0)作为输出。 - steabert
很可能你的GDB缺少Fortran支持。在foo处中断后,show language会显示当前源语言为“auto;当前为Fortran”。 - Hristo Iliev

11

我遇到了类似的问题并发现这个这个链接很有用。

总之,问题关键在于:如果你没有正确版本的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。


“*((datatype *)pointername )”这种表示法有点令人困惑。如果使用“( dtype ) ptrname”进行一次解引用,那么如何嵌套一次才能得到“((dtype *) ptrname)”呢? - Debanjan Basu

7

在 gdb 7.7.1 版本中,以下方法对我有效:

print A(1)@N

A代表数组,N代表要打印的元素数量。对于二维数组:

print A(1,1)@N

我知道这是一个老问题,但是在谷歌查询"gdb打印Fortran数组"会跳转到这里。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接