5
votes

I've been using using an underscore to define an integer as a specific kind in fortran.

Here is a snippet of code to demonstrate what 1_8 means, for example:

  program main
  implicit none

  integer(2) :: tiny
  integer(4) :: short
  integer(8) :: long

  tiny = 1
  short = 1
  long = 1

  print*, huge(tiny)
  print*, huge(1_2)

  print*, huge(short)
  print*, huge(1_4)

  print*, huge(long)
  print*, huge(1_8)

  end program main

Which returns (with PGI or gfortran):

32767
32767
2147483647
2147483647
9223372036854775807
9223372036854775807

I'm using the huge intrinsic function to return largest number of the given kind. So 1_8 is clearly the same kind as integer(8). This works for real numbers also, although I haven't shown it here.

However, I've been unable to find any documentation of this functionality and I don't remember where I learned it. My question is:

Is using _KIND standard fortran? Does anybody have a source for this?

Edit: It's been pointed out that the kind values I've used (2,4,8) are not portable - different compilers/machines may give different values for huge(1_4), for example.

3

3 Answers

6
votes

It is standard Fortran, as of Fortran 90, though the set of valid kind values for each type and the meaning of a kind value is processor dependent.

The Fortran standard is the definitive source for what is "standard" Fortran. ISO/IEC 1539-1:2010 is the current edition, which you can buy, or pre-publication drafts of that document are available from various places. https://gcc.gnu.org/wiki/GFortranStandards has a collection of useful links.

I would expect that many compiler manuals (e.g - see section 2.2 of the current PGI Fortran reference manual) and all reasonable textbooks on modern Fortran would also describe this feature.

4
votes

As already answered, this notation is standard fortran, but using these specific numeric values for kinds is not portable. Previous answers have described compilers that use other schemes. There are several other approaches that are portable.

First, use the kind scheme to define symbols, then use those symbols for numeric constants:

integer, parameter :: RegInt_K = selected_int_kind (8)
write (*, *) huge (1_RegInt_K)

Or use the kind definitions that are provided in the ISO_FORTRAN_ENV module, e.g.,

write (*, *) huge (1_int32)

The kinds of this module are specified in the number of bits used for storage. Some of the kinds are only available with Fortran 2008. If those are missing in your compiler, you can use the kind definitions provided with the ISO_C_BINDING, which is older.

2
votes

To add to IanH's answer the specification for an integer literal constant in Fortran 2008 is given in 4.4.2.2. Something like 1_8 fits in with R407 and R408 (for the obvious digit-string):

int-literal-constant is digit-string [_kind-param]
kind-param is digit-string or scalar-int-constant-name

You can find similar for other data types (although note that for characters the kind parameter is at the front of the literal constant).