15

In C/C++ to print a pointer as an array I usually do name@dimension. What is the equivalent for Fortran?

RSFalcon7
  • 2,241
  • 6
  • 34
  • 55

3 Answers3

16

Fortran 90 uses descriptors to represent the dimensions (the shape) of its arrays and to pass assumed-shape array arguments. Also pointers in Fortran are special - they can only point to qualified targets. This allows much better debugger introspection in Fortran than in C/C++. Just use print arr(index) or one of the info commands - no need for fancy stuff.

Sample code:

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

Compile with debug information and run with 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, ...

It cannot show the content of assumed-size array arguments for obvious reasons but you can print each element individually:

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

Note that printing array sections doesn't work on assumed-size array arguments as they are not passed by descriptor and gdb runs into trouble:

(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)
Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
  • That's really nice, but doesn't work for me, what is your gdb/gfortran version? (btw, your subroutine foo is missing an argument in the example) – steabert Aug 03 '12 at 13:02
  • `gfortran 4.4.6` (also tested with `4.7.0`) and `gdb 7.2-50.e16` on Scientific Linux 6.2 (RHEL 6.2). Did you compile with debugging information? (fixed the missing argument - 10x for pointing it out) – Hristo Iliev Aug 03 '12 at 13:06
  • 1
    thanks, maybe it's a bug of sorts, I don't know. I use gfortran 4.7.1 and gdb 7.4.1. I just get `(0)` as output if i print the arrays. – steabert Aug 03 '12 at 13:14
  • Probably your GDB is missing Fortran support. After breaking on `foo`, `show language` gives `The current source language is "auto; currently fortran".` – Hristo Iliev Aug 03 '12 at 13:21
11

I came across a similar problem and found this and this link useful.

It boils down to: if you don't have the right versions of gdb and gfortran, you need to do for example

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

or (in my case)

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

to print the 2nd element of the array. You can also do

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

to see array elements 2, ... , 2+5.

Matti Wens
  • 740
  • 6
  • 24
user2158166
  • 394
  • 4
  • 9
  • the `*((datatype *)pointername ) ` notation is slightly confusing. if dereferencing is done once with `( dtype *) ptrname` - how can nesting once lead to `*((dtype *) ptrname)`?? – Debanjan Basu May 12 '16 at 10:09
7

This works for me in gdb 7.7.1:

print A(1)@N

where A is the array and N is the number of elements to be printed. For a two-dimensional array:

print A(1,1)@N

I know this is an old question, but Google query "gdb print fortran array" leads here.

Jan Lachnitt
  • 71
  • 1
  • 2