Problem with a program: zero-sized array?
Arjen Markus
arjen.markus895@gmail.com
Wed Oct 13 11:28:00 GMT 2010
Hello,
I have run into a peculiar problem with the gfortran compiler (both on
Windows and Linux).
I have reduced the program to a bare minimum and that has made the
crash (access violation or
something similarly fatal) disappear, but the bug is still there. Here
is the output from the
program as I get it:
after retrieve int1d: 1 2 3 4
5 6 7 8 9
10
shape: 10
shape: 10
shape: ...
size: 1
This output is written by the following statements:
write(*,*) 'after retrieve int1d:', INT1D_RETRIEVED
write(*,*) 'shape:', shape(INT1D_RETRIEVED)
write(*,*) 'shape:', shape(INT1D)
write(*,*) 'shape:', shape(int1d_retrieved) == shape(INT1D), ' ...'
write(*,*) 'size: ', size(shape(int1d_retrieved) == shape(int1d))
(there is NOTHING in between)
The odd thing is the fourth line - it should have contained the one
logical value of the comparison.
In the full program a similar comparison causes the crash.
As you can see: the shape information is there on the third line and
the array int1d is simply a
fixed array.
I have tried the program with other compilers and they gave no problems.
I suspect this is caused by a bug in the gfortran compiler, but I
hesitate to draw that conclusion
right now - I have been too hasty with such conclusions in the past.
I'd appreciate any comments that can shed light on this.
Regards,
Arjen
---------
Source code for the program:
! test_store.f90 --
! Test program for the ftnunit_store module
!
module ftnunit_utilities
contains
subroutine ftnunit_get_lun( lun )
integer, intent(out) :: lun
lun = 10
end subroutine ftnunit_get_lun
end module ftnunit_utilities
module ftnunit_store
use ftnunit_utilities
implicit none
private
integer, parameter :: single = kind(1.0)
integer, parameter :: double = kind(1.0d0)
character(len=40), parameter :: ftnunit_header = 'FTNUNIT 1.0'
character(len=10), parameter :: ftnunit_integer = 'INTEGER'
interface test_retrieve_data
module procedure test_retrieve_data_integer1d
end interface
interface test_store_data
module procedure test_store_data_integer1d
end interface
public :: test_retrieve_data, test_store_data
public :: test_open_storage_file, test_close_storage_file
contains
subroutine test_open_storage_file( filename, lun, desc, output )
character(len=*), intent(in) :: filename
integer, intent(out) :: lun
character(len=*), intent(inout) :: desc
logical, intent(in), optional :: output
logical :: output_
character(len=80) :: desc_
character(len=40) :: header
integer :: ierr
output_ = .false.
if ( present(output) ) then
output_ = output
endif
!
! Get a LU-number, open the file and check
!
call ftnunit_get_lun( lun )
if ( output_ ) then
open( lun, file = filename, form = 'unformatted', status =
'new', iostat = ierr )
write( lun ) ftnunit_header
desc_ = desc
write( lun ) desc_ ! Ensure a known length of the description
else
open( lun, file = filename, form = 'unformatted', status =
'old', iostat = ierr )
read( lun, iostat = ierr ) header
read( lun, iostat = ierr ) desc_ ! Ensure a known length of
the description
desc = desc_
endif
end subroutine test_open_storage_file
subroutine test_close_storage_file( lun )
integer, intent(in) :: lun
close( lun )
end subroutine test_close_storage_file
subroutine test_store_data_integer1d( lun, data, desc )
integer, intent(in) :: lun
integer, intent(in), dimension(:) :: data
character(len=*), intent(in) :: desc
character(len=40) :: desc_
integer, dimension(10) :: dimensions
desc_ = desc
dimensions = 0
dimensions(1:1) = shape(data)
write( lun ) ftnunit_integer, 0, 1, dimensions, desc_
write( lun ) data
end subroutine test_store_data_integer1d
subroutine test_retrieve_data_integer1d( lun, data, desc )
integer, intent(in) :: lun
integer, pointer, dimension(:) :: data
character(len=*) :: desc
character(len=10) :: type
character(len=40) :: desc_
integer, dimension(10) :: dimensions
integer :: ierr
integer :: char_length
integer :: number_dims
read( lun, iostat = ierr ) type, char_length, number_dims, dimensions, desc_
allocate( data(dimensions(1)) )
read( lun ) data
desc = desc_
end subroutine test_retrieve_data_integer1d
end module ftnunit_store
!------------------------------------------------------------
program test_store
use ftnunit_store
implicit none
integer :: i, j, k
integer, dimension(10) :: int1d
integer, dimension(:), pointer :: int1d_retrieved
integer :: lun
character(len=60) :: description
character(len=80) :: desc_retrieved ! Different
length than description
description = 'Test file for ftnunit_store module'
int1d = (/ (i, i=1,10) /)
call test_open_storage_file( 'test_store.bin', lun, description, .true. )
call test_store_data( lun, int1d, 'integer array int1d' )
call test_close_storage_file( lun )
!
! Now retrieve the data and compare
!
call test_open_storage_file( 'test_store.bin', lun,
desc_retrieved, .false. )
if ( desc_retrieved /= description ) then
write(*,*) 'Difference in file description'
write(*,*) ' Expected: ', description
write(*,*) ' Actual: ', desc_retrieved
endif
call test_retrieve_data( lun, int1d_retrieved, desc_retrieved )
write(*,*) 'after retrieve int1d:', INT1D_RETRIEVED
write(*,*) 'shape:', shape(INT1D_RETRIEVED)
write(*,*) 'shape:', shape(INT1D)
write(*,*) 'shape:', shape(int1d_retrieved) == shape(INT1D), ' ...'
write(*,*) 'size: ', size(shape(int1d_retrieved) == shape(int1d))
call test_close_storage_file( lun )
end program
More information about the Fortran
mailing list