File_storage_size Question

It is Friday after a long week, and I’m not seeing something that may be obvious. Here is a small program

program xxx
   use iso_fortran_env, only: real64, file_storage_size
   integer :: wpsize
   inquire( iolength=wpsize ) 1.0_real64
   write(*,'(*(g0))') 'file_storage_size=', file_storage_size, ' bits. real64 storage=', wpsize, ' units.'
end program xxx

I compile and execute it in three different ways (this is on intel MacOS):

$ gfortran xxx.f90 && a.out
file_storage_size=8 bits. real64 storage=8 units.
$ ifort -assume byterecl xxx.f90 && a.out
file_storage_size=8 bits. real64 storage=8 units.
$ ifort xxx.f90 && a.out
file_storage_size=8 bits. real64 storage=2 units.

That last combination seems inconsistent. I was expecting file_storage_size to change to 32 bits. What am I missing?

The intel compiler defaults to 4-byte units, so opening a direct-access file with RECL=2 would create create a file with 8-byte records. With the --assume byterecl option the units for things like RECL are bytes so you would use RECL=8 to get 8-byte records. Hence the switch. Most new Fortran implementations typically default to RECL units of one byte. I have seen a lot of oversized direct access files when people are not aware of that. It still works but is four times bigger than needed!

Shouldn’t the file_storage_size value change to reflect that?

The INQUIRE statement was available in Fortran 9X, predating iso_fortran_env, so your test program is employing two different views of storage unit sizes. The following modification of your program

program xxx
   integer :: wpsize, recl
   inquire( iolength=wpsize ) 1.0d0
   write(*,'(A20,2x,i2,2x,A20)') ' bits. real_dp storage=', wpsize, ' units.'
end program xxx

works with Digital Visual Fortran as well as with modern compilers, and is blind to the notion of using a bit as a unit of measure.

The ifort -assume byterecl option applies only to unformatted files according to ifort’s man page. Direct access files may be either formatted or unformatted, and so may sequential files. See the f2018 standard 12.5.6.15.

The intel documentation for FILE_STORAGE_SIZE says:

Is the size of the file storage unit expressed in bits. To use this constant, compiler option assume byterecl must be enabled.

So the last combination above is indeed inconsistent, but since it is documented, it is a feature, not a bug. :wink:

The statement

    inquire( iolength=wpsize ) 1.0_real64

returns a value for unformatted files, so that part is alright. The other thing that is related to size is something like

    inquire( ...,size=isize ) 

Here the value that is returned is in file storage units, which are file_storage_size bits each. It looks like the variable isize must be default integer KIND, which leads to the question of what exactly is returned when the file size exceeds HUGE(0). Or can isize be any KIND?

It looks like gfortran and ifort both allow isize in

    inquire( ...,size=isize ) 

to be INT64, and it does work correctly for both compilers for files larger than 4GB. However, the documentation for other compilers states that isize must be a default KIND integer. I guess this is a quality of implementation issue.

1 Like