I don’t really trust my memory on this either, but gfortran has supported kind values of 4, 8, 10, and 16 for well over a decade now. The screwy thing to me about the gfortran implementation is that the 10-byte reals are stored in 16 bytes, so both of those kind values are stored in 128 bits, just with different precision and exponent ranges. I guess the REAL128 issue is then which of those two kind values, 10 or 16, was mapped to REAL128. I forget, when was REAL128 added to iso_fortran_env?
This issue of multiple kind values for a given storage size is not going away. Consider 32, 64, and 128-bit IEEE binary and decimal floating point kinds.
Regarding the question of when are the ISO parameters useful, consider this. What is the best way to access 64-bit integer and real kind values that can be storage sequence associated? One easy way is to use INT64 and REAL64. If instead you try to use selected_xxx_kind()
or the xxx_KINDS(:)
arrays, it requires further trickery to get the right matches.
This fallback can be done using merge()
or algebraic expressions, but it isn’t pretty. Here is an example from one of my codes (dated about 2004 I think).
integer, parameter :: COLUMBUS_WP = selected_real_kind(14)
integer, parameter :: COLUMBUS_EP_REQUESTED = selected_real_kind(17)
integer, parameter :: COLUMBUS_EEP_REQUESTED = selected_real_kind(30)
! the following initialization expressions are equivalent to:
! if ( COLUMBUS_EP_REQUESTED < 0 ) then
! COLUMBUS_EP = COLUMBUS_WP
! else
! COLUMBUS_EP = COLUMBUS_EP_REQUESTED
! endif
integer, parameter :: COLUMBUS_EP = (1+sign(1,COLUMBUS_EP_REQUESTED))/2 * COLUMBUS_EP_REQUESTED + &
& (1-sign(1,COLUMBUS_EP_REQUESTED))/2 * COLUMBUS_WP
integer, parameter :: COLUMBUS_EEP = (1+sign(1,COLUMBUS_EEP_REQUESTED))/2 * COLUMBUS_EEP_REQUESTED + &
& (1-sign(1,COLUMBUS_EEP_REQUESTED))/2 * COLUMBUS_EP
The *_REQUESTED values can be negative, the other ones are the fallback kind values. I think the merge()
equivalent expression is probably cleaner now, but I don’t think merge()
was allowed in an initialization expression when I first wrote this. With gfortran on intel hardware, these kind values are 8, 10, and 16, which is what I was after. On other compilers or other hardware, there are usually just two or sometimes even one distinct kind value.