title: "C pointer trickery" to allow mismatched Fortran array ranks
body: <p>I'm writing a HDF5 wrapper subroutine that will read/write a double precision array of <em>any</em> shape from/to a dataset inside a HDF5 file. To achieve this, I use some C pointer trickery such that the subroutine takes in only the first element of the array as <code>val</code>, but it actually reads/writes the whole array using the temporary buffer <code>buf(1:sz_buf)</code>.</p>
  <p>So far I have the following for the read subroutine (after removing error checks to keep it concise):</p>
  <pre><code>SUBROUTINE hdf5_read_array_d( fname, path, name, val, dims )
    USE ISO_C_BINDING, ONLY: C_SIZE_T, C_LOC, C_F_POINTER
  
    ! Input arguments
    CHARACTER(LEN=*), INTENT(IN) :: fname, path, name
    REAL(KIND(1.D0)), TARGET, INTENT(OUT) :: val
    INTEGER, DIMENSION(:), INTENT(IN) :: dims
  
    ! Internal variables
    INTEGER(KIND=HID_T) :: h5root, h5path, h5dset
    INTEGER(KIND=HSIZE_T), DIMENSION(SIZE(dims)) :: h5dims
    REAL(KIND(1.D0)), DIMENSION(:), POINTER :: buf
    INTEGER(KIND=C_SIZE_T) :: sz_buf
    INTEGER :: dim
  
    ! Open the file in read-only mode
    CALL h5fopen_f( TRIM(fname), H5F_ACC_RDONLY_F, h5root, ierr )
  
    ! Open the pre-existing path in the file as a group
    CALL h5gopen_f( h5root, TRIM(path), h5path, ierr )
  
    ! Open the dataset
    CALL h5dopen_f( h5path, TRIM(name), h5dset, ierr )
  
    ! Convert dims to HSIZE_T
    h5dims(:) = dims(:)
  
    ! C pointer trickery: cast double -&gt; void* -&gt; double*
    sz_buf = PRODUCT(dims)
    ALLOCATE( buf( sz_buf ) )
    CALL C_F_POINTER( C_LOC(val), buf, (/sz_buf/) )
  
    ! Read data from dataset through buffer
    CALL h5dread_f( h5dset, H5T_NATIVE_DOUBLE, buf, h5dims, ierr )
  
    ! Clean up and close HDF5 file
    NULLIFY(buf)
    CALL h5dclose_f( h5dset, ierr )
    CALL h5gclose_f( h5path, ierr )
    CALL h5fclose_f( h5root, ierr )
  
    RETURN
  END SUBROUTINE hdf5_read_array_d
  </code></pre>
  <p>Now, the question is, do I need to also put in <code>DEALLOCATE(buf)</code> in addition to / in place of the <code>NULLIFY(buf)</code>?</p>
  <p>Any help would be appreciated.</p>
  <p>Note: I am aware that Fortran 2018 includes assumed-rank arrays <code>val(..)</code> that will elegantly solve this problem. But again, it's a newer feature that might not be implemented by all compilers yet.</p>
  <p>Edit: On <code>C_F_POINTER()</code>, here's a screenshot of Metcalf, Reid, and Cohen (4th Edition, not the newest one that has Fortran 2018 stuff):
  <a href="https://i.stack.imgur.com/VUOB1.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VUOB1.png" alt="Metcalf_et_al_C_F_POINTER" /></a></p>