Major changes in Gfortran by version

Gfortran and Intel oneAPI are the most advanced modern Fortran compilers. Useful Fortran 2018 enhancements include:

oldest Gfortran version

Gfortran 8 is the oldest version currently maintained.

Intel oneAPI

  • Intel oneAPI has “full” Fortran 2018 support.

Gfortran major changes

Gfortran 10

  • select rank – making assumed rank arguments actually useful.

Gfortran 9

  • added random_init() to initialize the random generator seed…randomly

Gfortran 8.1

  • Optimization: automatic nested loop exchange with do concurrent
  • Checks: Actual argument array with too few elements for dummy argument now errors
  • Polymorphism: initial support for parameterized derived types (simply define kind at initialization)
  • Coarray: Initial support for teams

(Gfortran 8.2 and 8.3 did not introduce new Fortran features)

Gfortran 8

  • std=f2008ts deprecated, do not use as it errors on compiling error stop for Gfortran < 8.
  • std=f2018 added

Gfortran 7

  • Polymorphism: derived type IO select type etc. fully supported from Fortran 2003.
  • Fortran 2018: Non-constant stop and error stop codes
  • Compatibility: -fdec- options help compiling very old non-standard code that was previously only compatible with Intel oneAPI (of DEC heritage).

Gfortran 6

Fortran 2008: submodule support, useful for large projects to save compilation time and allow powerful use scenarios

Fortran 2003: improved support for deferred-length character. These are very useful for avoiding bothersome trim() everywhere. Example:

character(256) :: argv
character(:), allocatable :: filename

call get_command_argument(1, argv)
filename = trim(argv)

end program

In this example, filename is now exactly the length required to fit the text. If the filename (in argv) was “hello.txt” then len(filename) is 9. That is, len_trim == len with auto-allocated characters (unless subsequently rewritten with a shorter string).

Practical examples are in gitrev.f90 and split_string.f90. For split_string.f90, note that this is the proper way to avoid assumed-length character functions, which are obsolete as of Fortran 95. Specifically:

Bad:

! don't do this!
character(*) function myfun(a)

Good:

pure function myfun(a)
character(:), allocatable :: myfun

Gfortran 5

  • OpenMP 4.0 fully supported
  • Fortran 2003: ieee_ intrinsics supported, allowing convenient standard-compliant use of nan, ieee_is_nan, etc.
  • Fortran 2008: Initial coarray support
  • Fortran 2008: error stop in pure procedures, but only without specifying std= (until Gfortran 8 std=f2018). Error code must be constant.

Gfortran 4.9

  • Fortran 2003: allow deferred-length character variables in derived types

Gfortran 4.8

By this release, substantial Fortran 2008 polymorphism support had been initially added, including

  • select type
  • class(*)
  • type(*)
  • assumed rank dimension(..)

Gfortran 4.6

Gfortran 4.6 is the first version of Gfortran basically usable with commonly used code beyond Fortran 95.

  • Fortran 2003: deferred-length character variable (not in derived types until 4.9)
  • Fortran 2008: impure elemental support

Gfortran 4.5

  • Fortran 2008: iso_fortran_env real64 etc. added

Gfortran 4.4

Gfortran 4.4 added initial support for polymorphism.

  • OpenMP 3

Operating system vs. Gfortran version:

Here are a few common operating systems vs. easily available Gfortran version. CentOS should use devtoolset.

Cygwin

Homebrew

Ubuntu / Debian

  • Ubuntu gfortran repo defaults

  • Get recent Gfortran via PPA

  • Ubuntu 20.04 default: gfortran-9

  • Ubuntu 18.04 default: gfortran-7

  • Ubuntu 16.04 default: gfortran-5

  • Debian Buster, including Raspberry Pi: gfortran-8

CentOS / RHEL

  • release 8 (EOL 2029): gfortran-8

  • release 7 (EOL 2024) devtoolset-8: gfortran-8

  • release 7 EPEL: gfortran-4.9

  • release 7 default: gfortran-4.8

CMake

CMake allows switching parameters based on compiler version. This is very useful for modern Fortran programs.

Fortran 2018

Example CMakeLists.txt for Fortran compiler version dependent options.

if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)

  # option applying to any language for this compiler
  add_compile_options(-mtune=native)

  # language-specific, note LEADING space
  string(APPEND CMAKE_Fortran_FLAGS " -fimplicit-none")

  if(CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL 8)
    string(APPEND CMAKE_Fortran_FLAGS " -std=f2018")
  endif()

endif()

add_executable(myprog main.f90)

Non-Fortran 2018 workaround

Here we assume that assert.f90 contains error stop in a procedure that’s called from a pure procedure.

include(CheckFortranSourceCompiles)
check_fortran_source_compiles("character :: a; error stop a; end"
  f18errorstop SRC_EXT f90)

add_executable(myprog PRIVATE main.f90)

if(f18errorstop)
  target_sources(myprog PRIVATE assert.f90)
else()
  target_sources(myprog PRIVATE assert_old.f90)
endif()

Notes