如何将假定秩数组写入文件?Intel Fortran编译报错求助
The error you're seeing (#8842: An I/O list item must not be an assumed rank object) happens because Intel Fortran (ifort) doesn't yet support direct I/O operations on assumed-rank arrays, even though this is allowed by the Fortran 2018 standard. Here are two practical workarounds to get your code working:
1. Use select rank to Handle Specific Array Ranks
Since assumed-rank arrays can be inspected with the select rank construct, you can branch your code to handle each possible array dimension explicitly. This works because within each branch, the array is treated as a fixed-rank object, which ifort allows in I/O statements:
subroutine write_dbl_gen(filename, array) Implicit None character(len=*), intent(in) :: filename real(8), intent(in) :: array(..) integer :: p_un ! Open the stream file open(unit=p_un, file=filename, form="unformatted", access="stream", status="replace") select rank(array) rank(1) write(p_un) array rank(2) write(p_un) array rank(3) write(p_un) array ! Add more rank branches here if you need to support higher dimensions rank(*) ! Handle unsupported ranks with an error error stop "write_dbl_gen: Array rank not supported" end select close(unit=p_un) end subroutine write_dbl_gen
This approach is straightforward and maintains the original array's binary layout in the file, just like writing a fixed-rank array directly.
2. Use C Interoperability to Write the Array as Raw Bytes
If you want a solution that works for any rank without writing separate branches, you can use Fortran's C interoperability features to treat the array as a contiguous block of bytes. This bypasses the fixed-rank requirement for I/O by converting the array to a 1D byte array:
subroutine write_dbl_gen(filename, array) use, intrinsic :: iso_c_binding Implicit None character(len=*), intent(in) :: filename real(8), intent(in) :: array(..) integer :: p_un, total_bytes type(c_ptr) :: array_ptr character(1), pointer :: byte_buffer(:) ! Calculate total number of bytes in the array total_bytes = storage_size(array) * size(array) / 8 ! Get a C pointer to the array's data array_ptr = c_loc(array) ! Convert the C pointer to a Fortran pointer to a 1D byte array call c_f_pointer(array_ptr, byte_buffer, [total_bytes]) ! Write the byte buffer to the stream file open(unit=p_un, file=filename, form="unformatted", access="stream", status="replace") write(p_un) byte_buffer close(unit=p_un) end subroutine write_dbl_gen
This method writes the exact binary representation of the array from memory to the file, which is identical to writing a fixed-rank array directly. It works for any array rank, no matter how high.
Bonus: Check Compiler Support
If possible, consider upgrading to the latest version of Intel Fortran (now part of Intel oneAPI) — newer versions may have improved support for Fortran 2018 features like assumed-rank I/O. Alternatively, GNU Fortran (gfortran) has supported direct I/O on assumed-rank arrays for several versions, so your original code might work without modifications if you switch compilers.
内容的提问来源于stack exchange,提问作者Stein

