What’s New and Fortran 2028 Preview

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

This page is written against Fortran 2023 (ISO/IEC 1539-1:2023, read here through the free final draft J3/23-007r1) and looks ahead to Fortran 2028, read through the public working draft J3/26-007r1 of 3 March 2026. Everything that can be compiled was checked on 2026-10-19 with GNU Fortran (gfortran) 16.2 and LLVM Flang 23 in a container (aarch64): the programs of this page use -std=f2023 -Wall -Wextra -pedantic -fimplicit-none -fcheck=all for gfortran, and the output shown is real output. Fortran 2028 is described only as "upcoming": its Committee Draft (WG5 N2258) is not a public document, WG5 lists it on its documents page on 13 July 2026, and the outcome of the ballot is not shown there, so this page says "committee draft stage" and nothing more precise. The working draft changes between meetings: the copy read for this page still contains open "Unresolved Technical Issue" notes, so every syntax shown for Fortran 2028 is the draft’s, not a promise.

The page has five jobs. First, it gives a version-by-version summary and points to the history page for the detail. Second, it lists every change that Fortran 2023 made (the Introduction of the standard has the complete list), says which page of this section covers each one and which of the two installed compilers accepts it. Third, it states what is known about Fortran 2028: its work items, what it makes obsolescent, and what the two compilers do with the draft syntax today. Fourth, it collects in one table the places where the reference books are outdated, which the other pages of this section note one topic at a time. Fifth, it records the errata of the main reference book, described in my own words. The running example is the heatflow project introduced in Getting Started.

Related pages: History, Standards and Compilers (the history, the revision process and the per-compiler support table, which this page does not repeat in full), Legacy Features and Modernization (the deleted and obsolescent features in depth) and Cheat Sheet.

A version-by-version summary

Each revision of the standard is an upward-compatible extension of the previous one, with a short list of exceptions that is given for Fortran 2023 below. The table is a map of where to look in this section; the headline features and the technical reports folded into each revision are on the history page.

Revision What to remember Where this section covers it

Fortran 90

Free form, modules, derived types, whole-array operations, allocatable arrays and pointers, select case, kind parameters, optional and keyword arguments.

Program Structure and Source Form, Modules and Submodules, Arrays Fundamentals

Fortran 95

pure and elemental procedures, default initialization of components, null(); forall (obsolescent since Fortran 2018).

Procedures, Functions and Subroutines

Fortran 2003

Type extension, polymorphism, type-bound procedures, parameterized derived types, iso_c_binding, procedure pointers, derived-type and stream I/O, IEEE modules.

Object Oriented Programming, Interoperability with C, Floating-Point and IEEE Arithmetic

Fortran 2008

Coarrays, submodules, do concurrent, contiguous, block, error stop, bit and special-function intrinsics, newunit=.

Coarrays, Images and Synchronization, do concurrent and GPU Offload

Fortran 2018

Teams, events, collectives, atomics, assumed rank and select rank, implicit none (type, external), generic statement, reduce, random_init, locality specifiers.

Coarray Teams, Events, Collectives and Atomics, Array Arguments: Assumed Shape, Size and Rank

Fortran 2023

10,000-character lines, conditional expressions, enumeration types, typeof/classof, split/tokenize, degree and half-revolution trigonometry, at and leading-zero editing, simple procedures, put with notify, IEEE 60559:2020. The full list is in the next section.

Every page of this section; the table below says which

Fortran 2028

Committee draft stage: templates, generic subprograms, default kind, protected_target, prefix reductions, new math functions and source-location procedures.

This page, and the "Fortran 2028" remarks of the pages that name it

The WG5 papers that summarise each revision in prose are N2212 (Fortran 2023), N2161 (Fortran 2018), N1891 (Fortran 2008) and N1648 (Fortran 2003); they are listed in the references of this page.

Fortran 2023: the complete list of changes

The Introduction of J3/23-007r1 lists the extensions of Fortran 2023 under eight headings. The table below follows that list item by item, so nothing the standard calls new is missing, and adds the clause that defines the item, the page of this section that explains it and what the two installed compilers did on 2026-10-19. The standard also changed the foreword: it states that conformance with ISO/IEC 60559:2020 is now part of the language, as one of the "main changes".

Compiler legend: Y the probe or the page’s example compiled and gave the expected result; N rejected, crashed, or the behaviour is wrong or missing; A accepted by the parser but not exercised. These are the results recorded on the pages that cover each feature, mostly the support table of the history page. Intel ifx, NAG and Cray are not installed here; for them use the table on History, Standards and Compilers, which quotes their release notes.

Change (Introduction of J3/23-007r1) Clause Covered on gfortran 16.2 Flang 23

Source form

Free-form lines of up to 10,000 characters, statements of up to 1,000,000 characters, no limit on continuation lines

6.3.2.1, 6.3.2.6

Program Structure and Source Form

Y

Y

Data declaration

A data object with a coarray component may be an array or allocatable

Introduction

Coarray Teams, Events, Collectives and Atomics

N

A

bind(c) enumerations renamed interoperable enumerations, and an interoperable enumeration may be given a type name

7.6.1

Enumerations

N (named form)

N (named form)

Non-interoperable enumeration types (enumeration type)

7.6.2

Enumerations

N

N

typeof and classof type specifiers

7.3.2.1

Generic and Rank Independent Programming, Variables, Declarations and Attributes

N

A (typeof)

A public namelist group may contain private objects

8.9

Internal Files, Namelist and Non-Advancing I/O

N

N

The rank-independent dimension form: the rank clause

8.5.8, 8.5.17

Generic and Rank Independent Programming, Arrays Fundamentals

N

Y

Data usage and computation

Binary, octal and hexadecimal constants in more contexts

7.7

Intrinsic Types and Kinds

N (assignment form)

Y

A deferred-length allocatable errmsg= variable is allocated by the processor

9.7.5

Allocatable Arrays and Dynamic Memory

N

N

Array bounds of an allocate given by integer arrays

9.7.1.1

Allocatable Arrays and Dynamic Memory

N

N

Lower bounds and rank remapping in a pointer assignment given by integer arrays

10.2.2.3

Pointers and Targets

N

N

Integer arrays as multiple subscripts and subscript triplets (the @ form)

9.5.3.2

Arrays Fundamentals, Generic and Rank Independent Programming

N

N

Conditional expressions, (c ? a : b)

10.1.2.3

Expressions and Assignment, Control Flow

Y (scalar; see the crash below)

Y

Input/output

The at edit descriptor: output of character values with trailing blanks removed

13.7.4

Format Specifications and Edit Descriptors

N

Y

leading_zero= in open and write, and the lz, lzp and lzs edit descriptors

12.5.6.12, 12.6.2.10, 13.8.5

Format Specifications and Edit Descriptors, Input/Output: Units and Files

N

Y

A deferred-length allocatable iomsg= variable is allocated by the processor

12.11.6

Internal Files, Namelist and Non-Advancing I/O

N

N

A deferred-length allocatable scalar unit of an internal write is allocated to the record length

12.4

Internal Files, Namelist and Non-Advancing I/O

N

N

Execution control

The reduce locality specifier of do concurrent

11.1.7

do concurrent and GPU Offload

Y

Y

Put with notify: notify wait, notify= in an image selector, notify_type

11.6

Coarray Teams, Events, Collectives and Atomics

N

not available

Intrinsic procedures

Trigonometry in degrees: acosd, asind, atand, atan2d, cosd, sind, tand

16.9

Intrinsic Procedures Overview

Y

Y

Trigonometry in half-revolutions: acospi, asinpi, atanpi, atan2pi, cospi, sinpi, tanpi

16.9

Intrinsic Procedures Overview

Y

Y

selected_logical_kind

16.9.182

Intrinsic Types and Kinds

Y

Y

split

16.9.196

Characters and Strings

Y

Y

tokenize

16.9.210

Characters and Strings

N (link error)

Y

system_clock supports more than one clock, selected by the kind of its arguments

16.9.202

Intrinsic Procedures Overview

Y

Y (mixed kinds not diagnosed)

A deferred-length allocatable actual argument of an intrinsic procedure is allocated by the processor

16.2

Intrinsic Procedures Overview

N

N

A collective subroutine may succeed on one image although an error condition occurs on another

16.6

Coarray Teams, Events, Collectives and Atomics

not exercised

not exercised

Intrinsic modules

logical8, logical16, logical32, logical64 and real16 in iso_fortran_env

16.10.2

Intrinsic Modules and iso_fortran_env

Y (real16 is -2 on this host)

Y (real16 is 2)

The rounding and underflow get/set procedures of ieee_arithmetic, and ieee_get_modes, ieee_get_status, ieee_set_modes, ieee_set_status are pure and simple

17.11

Floating-Point and IEEE Arithmetic

the setters are still impure

the setters are still impure

c_f_strpointer and f_c_string in iso_c_binding

18.2.3.5, 18.2.3.9

Interoperability with C, Characters and Strings

f_c_string Y, c_f_strpointer N (link error)

Y

c_f_pointer has an optional lower= argument

18.2.3.3

Interoperability with C

Y

Y

New ieee_max, ieee_max_mag, ieee_min, ieee_min_mag; ieee_max_num, ieee_max_num_mag, ieee_min_num, ieee_min_num_mag now follow ISO/IEC 60559:2020 for zeros and NaNs

17.11.17 to 17.11.24

Floating-Point and IEEE Arithmetic

N

Y

Program units and procedures

simple procedures

15.8

Procedures, Functions and Subroutines

N

Y

Conditional arguments, including .nil.

15.5.2.3

Procedures, Functions and Subroutines

N

N

Three observations follow from the table. The language features that touch only the parser (long lines, reduce, the trigonometric intrinsics, selected_logical_kind, split) are already portable between the two free compilers. The features that need runtime support or deep semantic work (deferred-length allocation by the processor, enumeration types, integer arrays as subscripts and bounds, put with notify) are not implemented in either, and for those the portable code uses the Fortran 2018 idiom. And the two compilers fail in different places, so a feature that one accepts is not a reason to rely on it. The next section shows a program that uses only the features in the portable column.

A Fortran 2023 program that two compilers accept

The program below combines five of the Fortran 2023 additions that both compilers implement: trigonometry in degrees and in half-revolutions, selected_logical_kind, the split subroutine, a conditional expression and the reduce locality specifier of do concurrent. It is the practical answer to "what can I use today without checking?".

! A small program using only Fortran 2023 additions that gfortran 16.2 and Flang 23
! both accept and run: degree/half-revolution trigonometry, selected_logical_kind,
! split, a conditional expression, and a reduce locality specifier.
program portable_f2023
  use, intrinsic :: iso_fortran_env, only: real64
  implicit none
  integer, parameter :: dp = real64
  character(len=*), parameter :: spec = 'nx=64;ny=32'
  integer :: start, finish, count_items, i, total
  real(dp) :: a(4), mag
  logical(selected_logical_kind(8)) :: flag

  ! trigonometry in degrees and in half-revolutions
  print '(a,2f6.3)', 'sind/cospi:', sind(30.0_dp), cospi(1.0_dp / 3.0_dp)

  ! logical kind selected by size in bits
  flag = .true.
  print '(a,i0,l2)', 'logical kind and value:', kind(flag), flag

  ! split walks the tokens of a string one by one
  start = 1
  finish = 0
  count_items = 0
  do
    call split(spec, ';', finish)
    count_items = count_items + 1
    print '(a,a)', 'token: ', spec(start:finish - 1)
    start = finish + 1
    if (finish > len(spec)) exit
  end do
  print '(a,i0)', 'tokens: ', count_items

  ! conditional expression (scalar)
  a = [1.0_dp, -2.0_dp, 3.0_dp, -4.0_dp]
  mag = (a(2) < 0.0_dp ? -a(2) : a(2))
  print '(a,f5.1)', 'abs of a(2) via ?: ', mag

  ! reduce locality in do concurrent
  total = 0
  do concurrent (i = 1:10) reduce(+: total)
    total = total + i
  end do
  print '(a,i0)', 'sum 1..10 = ', total
end program portable_f2023
sind/cospi: 0.500 0.500
logical kind and value:1 T
token: nx=64
token: ny=32
tokens: 2
abs of a(2) via ?: 2.0
sum 1..10 = 55

The output is identical with gfortran 16.2 (-std=f2023 with the warning flags above, no diagnostics) and Flang 23 (flang-23 with default options). The value 1 printed for the logical kind is the kind number for an 8-bit logical, a processor-dependent number; use the named constants of iso_fortran_env if you need to name the kind.

A compiler crash to know about: a conditional expression as an output item

One combination is not safe in gfortran 16.2: a conditional expression used directly as an item of an output list. The program is valid Fortran 2023 and Flang runs it; gfortran 16.2 stops with an internal compiler error (ICE), with or without -fcheck=all:

program ice_probe
  implicit none
  real :: a
  a = -2.0
  print '(f5.1)', (a < 0.0 ? -a : a)
end program ice_probe
ice_probe.f90:5:36:

    5 |   print '(f5.1)', (a < 0.0 ? -a : a)
      |                                    ^
internal compiler error: in fold_convert_loc, at fold-const.cc:2672

Flang 23 prints 2.0 for the same file. The workaround, used in the program above, is to assign the conditional expression to a variable and print the variable. Assignment, as in the heatflow time-step function on the history page, works with both compilers.

Compatibility with Fortran 2018

Section 4.3.3 of the standard lists the few cases where a conforming Fortran 2018 program can change meaning or stop being conforming under Fortran 2023: the integer arguments of one system_clock reference must now have the same kind; a block variable declared only by a data statement cannot be used before the statement; the pointer and target arguments of associated cannot have different ranks; deferred-length allocatable character variables assigned by iomsg=, errmsg=, an internal write or an intent(out) argument of an intrinsic subroutine get intrinsic-assignment semantics; and the ieee_max_num family returns the number when the other argument is a signaling NaN. They are explained, with a system_clock example that gfortran rejects under -std=f2023, on History, Standards and Compilers. Everything else that a Fortran 2018 program does still means the same in Fortran 2023.

Corrigendum 1 of Fortran 2023 (ISO/IEC 1539-1:2023/Cor 1:2026) was published in January 2026; its draft is WG5 N2244. It is a set of corrections, not new features. The free text used by this section, J3/23-007r1, predates it, so for contractual work check a clause against the ISO text and the corrigendum.

Fortran 2028

Fortran 2028 (formerly called "F202Y") is the revision after Fortran 2023. Its status, as far as public sources show:

  • Committee draft stage. WG5 lists "N2258 Fortran 2028 Committee Draft" as a document that is not public, on its documents page dated 13 July 2026. The ballot outcome is not published there. The standard itself is not published, and no edition of ISO/IEC 1539-1 for it exists.

  • A public working draft exists. J3/26-007r1 ("Fortran 2028 Working Draft", 3 March 2026) is the text read for this page. Its foreword says the sixth edition cancels and replaces the fifth (ISO/IEC 1539-1:2023), and names three main changes: templates, generic subprograms, and the specification of the default kinds of the intrinsic types.

  • Publication is targeted for the second half of 2028, the schedule quoted when this section was planned; I could not confirm the date on a public page, so treat it as a target.

  • Compatibility. The draft’s Introduction states that a conforming Fortran 2023 program not affected by the listed limitations is a conforming Fortran 2028 program.

The documents to follow are the J3 papers (https://j3-fortran.org/), the WG5 page for the revision (wg5-fortran.org/f2028.html), which on the check date only says that Fortran 2028 is the working title of the revision after Fortran 2023, and the public proposals repository (j3-fortran/fortran_proposals). I could not read the WG5 work item list (N2261) or the Convenor’s report (N2262): the file name tried returned "not found". The list below therefore follows the working draft itself, which is the authoritative description of what is in the revision at this point.

The work items in the working draft

The draft’s Introduction lists the extensions under the same eight headings as Fortran 2023. The table gives each item, the clause of J3/26-007r1 that defines it (clause numbers differ from Fortran 2023 because the draft adds the template clause as clause 16, so the intrinsic procedures are in clause 17) and which page of this section mentions it.

Item in J3/26-007r1 Clause Mentioned on

Templates: the template construct with deferred arguments, requirements (requirement, require), and instantiation (instantiate)

16

Generic and Rank Independent Programming, Parameterized Derived Types

Generic subprograms: a subprogram declared generic defines a set of unnamed specific procedures with one generic name; select generic rank and select generic type constructs for ad-hoc specialisation

11.1.10, 11.1.11

Generic and Rank Independent Programming

The default kind statement: specify the default kinds of real, integer, logical and character in a scoping unit, and the default_kinds clause of use

8.7

Intrinsic Types and Kinds

The protected_target attribute: a data pointer whose target cannot be defined, or become undefined, through the pointer

8.5.16, 8.6.14

this page only

Types with the pure or simple attribute, usable as results and intent(out) arguments of pure and simple polymorphic procedures

7.5

this page only

Accessibility of an enumerator, and of an enum type name, in the statement that declares it; interoperability with the enum syntax of ISO/IEC 9899:2024

7.6.1, 7.6.2

Enumerations

Scoped access to an enumerator through the type name, type%enumerator

9.5

Enumerations

Enumeration-type values in list-directed and namelist I/O and with the g edit descriptor

12, 13

Enumerations

Adding all the specifics of a generic name to a generic operator, defined assignment or defined I/O without listing them

15

this page only

An implied-shape named constant with the rank clause; a scalar or simply contiguous assumed-rank target as the target of rank remapping; a polymorphic assumed-rank selector in select type; pointers of type real associated with complex targets and the reverse

8.5.17, 10.2.2, 11.1.13

Array Arguments: Assumed Shape, Size and Rank

The team argument of collective subroutines, the completion argument and the complete subroutine (non-blocking collectives)

17.6, 17.9.64

Coarray Teams, Events, Collectives and Atomics

Prefix reductions: reduce_prefix_exclusive, reduce_prefix_inclusive, sum_prefix_exclusive, sum_prefix_inclusive, and the collective co_sum_prefix_*, co_reduce_prefix_*

17.9

Coarray Teams, Events, Collectives and Atomics

New math functions related to the recommended operations of ISO/IEC 60559:2020: compound, expm1, exp10m1, exp2m1, log10p1, log2, log2p1, logp1, rootn, rsqrt

17.9

this page only

iso_fortran_env source-location functions procedure_name, source_file, source_line, and the constant function max_rank

17.10.2

Intrinsic Modules and iso_fortran_env

iso_c_binding constants c_float16, c_float32, c_float64, c_float128, c_float32x, c_float64x, c_float128x, c_decimal32, c_decimal64, c_decimal128, and matching CFI_type_t macros in ISO_Fortran_binding.h

19.2, 17.10

Interoperability with C, C Descriptors and ISO_Fortran_binding

Default implicit typing and the Dw.d edit descriptor become obsolescent

B.3.14, B.3.15

Format Specifications and Edit Descriptors, Legacy Features and Modernization

Three of the items are the ones that change how code is written, and are explained below: templates and generic subprograms, the default kind statement, and the newly obsolescent features. The others are small and are shown only as compile attempts.

Templates and requirements

Clause 16 of the draft, "Templates, requirements, and instantiation", is the largest addition. A template is a construct in a module, a main program or another template. It is parameterized by deferred arguments (deferred types, deferred constants and deferred procedures) and contains declarations, derived types and procedures written in terms of them. Instantiation with an instantiate statement gives the scoping unit access to the public entities of the template, built for the arguments you supply. A requirement is a named set of deferred-argument declarations, stated once and reused with require, which says what an argument must provide (the counterpart of a concept or a trait). A templated subprogram is a procedure that is itself a template and can be instantiated inline at the point of the call. The Fortran 2023 rank clause and rank intrinsic matter here, because they are what lets a template declare an entity whose rank depends on a deferred argument (the draft calls such an entity implied-rank).

The syntax in the draft’s examples puts the instantiation arguments in braces. The program below is a swap routine written as a template, followed by an instantiation for integer. It is the draft’s syntax, assembled from the grammar rules R1601 to R1626 of 16.1 to 16.5; no compiler accepts it, and it was not run. It exists to show the shape of the feature, and the diagnostics below show what the two compilers say today.

! Fortran 2028 draft (clause 16): TEMPLATE with a deferred type and INSTANTIATE {...}.
module swap_m
  implicit none
  template swap_tmpl(t)
    deferred type :: t
  contains
    subroutine swap(a, b)
      type(t), intent(inout) :: a, b
      type(t) :: tmp
      tmp = a
      a = b
      b = tmp
    end subroutine swap
  end template swap_tmpl
end module swap_m

program template_probe
  use swap_m
  implicit none
  instantiate swap_tmpl {integer}, only: swap_int => swap
  integer :: i, j
  i = 1
  j = 2
  call swap_int(i, j)
  print '(2(i0,1x))', i, j
end program template_probe

The first lines of what gfortran -std=f2023 -c (and -std=f202y, which gives the same) prints:

04_template.f90:4:3:

    4 |   template swap_tmpl(t)
      |   1
Error: Unclassifiable statement at (1)
04_template.f90:8:14:

    8 |       type(t), intent(inout) :: a, b
      |              1
Error: Derived type 't' at (1) is being used before it is defined

and Flang 23 stops at the first statement, because it cannot parse the construct:

error: Could not parse 04_template.f90
04_template.f90:4:4: error: expected declaration construct
    template swap_tmpl(t)
     ^

The plain Fortran 2023 ways to get the same result today are the techniques on Generic and Rank Independent Programming (generic interfaces with one specific per type, class(*), include files and the preprocessor). A template-based library will not be portable until compilers implement the clause, so any code written against the draft is an experiment.

Generic subprograms and select generic

A subprogram declared generic defines a family of unnamed specific procedures under one name. Its dummy arguments are declared with ranges (for rank, rank(0:7); for type, a type-generic argument), and the construct select generic rank or select generic type supplies the body that differs between specifics, selecting at compile time one block for each instance. The draft’s own example of select generic rank has a block for rank 0, a block for ranks 1 to 3 and a rank default block for ranks 4 to 7, which replaces seven hand-written specifics and the generic interface that lists them. The fragment below is that idea with the draft’s keywords, and it is also rejected by both compilers.

! Fortran 2028 draft (11.1.10): generic subprogram with SELECT GENERIC RANK.
module fill_m
  implicit none
contains
  generic subroutine fill(x)
    real, rank(0:2) :: x
    select generic rank (x)
    rank (0)
      x = 0.0
    rank default
      x = 1.0
    end select
  end subroutine fill
end module fill_m

gfortran reports Error: Expected '::' at (1) at the generic subroutine line (and then Invalid character in name at the rank(0:2) declaration); Flang 23 reports error: expected 'END' at the same line. Compare the select rank construct of Fortran 2018, which is available today and selects a block at run time for an assumed-rank dummy argument (see Array Arguments: Assumed Shape, Size and Rank).

The default kind statement

Many numerical codes need to change the precision of every unadorned real in a file. Today that is done with compiler options (-fdefault-real-8 in gfortran), which are not standard, change the meaning of all real declarations in the build, and are a classic source of mismatch errors (see Intrinsic Types and Kinds and Compilers and Compiler Options). The draft adds a standard statement, default kind (integer = selected_int_kind(18)), that sets the default kind of one or more of real, integer, logical and character in a scoping unit; the default kind of complex always follows that of real. A use statement with a default_kinds clause takes the defaults of a module. The statement is processed per scoping unit, so different modules of one build can use different defaults. Neither compiler accepts it:

01_default_kind.f90:4:3:

    4 |   default kind (integer = selected_int_kind(18))
      |   1
Error: Unclassifiable statement at (1)

That is gfortran 16.2; Flang 23 says error: expected declaration construct. Until then, real(dp) with a kind from a module such as heatflow's heatflow_kinds is the portable way to state the precision.

What becomes obsolescent

The standard defines two categories: deleted features (not required by the standard) and obsolescent features, which the standard keeps but recommends against and which a processor must be able to report. The draft’s Annex B was compared with the Fortran 2023 Annex B:

  • Deleted features. Nothing new. B.1 (the Fortran 90 features dropped by Fortran 95) and B.2 (the arithmetic if statement and the nonblock do, deleted in Fortran 2023) are the same in both.

  • Obsolescent features. Fortran 2023 lists twelve (alternate return, computed go to, statement functions, data statements among executable statements, assumed-length character functions, fixed source form, the character* form of a declaration, entry, the label form of do, common and equivalence with block data, specific names of intrinsic functions, and forall). The Fortran 2028 draft lists fourteen: the same twelve plus two additions. B.3.14 is the Dw.d edit descriptor and B.3.15 is default implicit typing (the rule that gives an undeclared name starting with i to n the type integer and any other the type real). The implicit statement itself and implicit none are not deleted by this: the obsolescent item is the default mapping.

For the working programmer this changes nothing today (both are still accepted) but confirms the advice of this whole section: write implicit none in every program unit, and use e or es editing instead of d. See Variables, Declarations and Attributes, Format Specifications and Edit Descriptors and Legacy Features and Modernization.

Not in the draft: I searched the text of J3/26-007r1 for a standard preprocessor, namespaces and a looping construct that is independent of rank, and found no corresponding text. So a statement that Fortran 2028 will have a standard preprocessor, namespaces or rank-independent looping has no support in the draft; only the items in the table above are in it.

What the compilers do with the other items

The remaining items are small, and each is a one-line test. The probe programs below were compiled with gfortran -std=f2023, with gfortran -std=f202y (the compiler’s switch for "experimental proposed features") and with Flang 23. Every one was rejected by all three, and -std=f202y changed no result for these items. The messages are the compilers' own.

Probe (draft feature) gfortran 16.2 Flang 23

integer, pointer, protected_target :: p => null()

Error: Invalid character in name at (1)

error: expected '::'

log2(x), expm1(x), rootn(x, 3), rsqrt(x) called with implicit none

Error: Function 'log2' at (1) has no IMPLICIT type (and the same for each of the other three names)

error: No explicit type declared for 'log2' (and the same for the others)

sum_prefix_inclusive(a)

Error: Function 'sum_prefix_inclusive' at (1) has no IMPLICIT type

error: No explicit type declared for 'sum_prefix_inclusive'

use, intrinsic :: iso_fortran_env, only: source_file, source_line, procedure_name

Error: Symbol 'source_file' referenced at (1) not found in intrinsic module ISO_FORTRAN_ENV

error: 'source_file' not found in module 'iso_fortran_env'

type, pure :: shape_t

Error: Mangled derived type definition at (1)

error: expected 'PUBLIC'

generic subroutine fill(x) with select generic rank

Error: Expected '::' at (1)

error: expected 'END'

template and instantiate

Error: Unclassifiable statement at (1)

error: expected declaration construct

default kind (integer = ...)

Error: Unclassifiable statement at (1)

error: expected declaration construct

The sources of the probes are single short files, one per row, compiled with the container scripts of this section. For the team= argument of the collectives, see the compiled example on Coarray Teams, Events, Collectives and Atomics; for the scoped enumerators, see Enumerations. As with every row of this page: the compilers' answer on the check date is not a statement about their roadmap, and the probe says only that the syntax of the draft, as read from J3/26-007r1, is not accepted.

Where the books are outdated

Each page of this section notes, topic by topic, where the reference books differ from the current standard and from current practice. The table collects those notes in one place, grouped by area, so that a reader of the books can check them at a glance. MRCB is Modern Fortran Explained: Incorporating Fortran 2023 (Metcalf, Reid, Cohen and Bader, 3rd edition, Oxford University Press, 2023), the main reference; "the MATLAB book" is the MathWorks API reference (R2023a). The books are good references to the language. What they cannot say is what happened after they were written, and what compilers do.

Area Outdated in the books, and the current position Details on

Standard identity

MRCB never gives the ISO number or date of Fortran 2023. It is ISO/IEC 1539-1:2023 (November 2023), with Corrigendum 1 (2026); the free text is J3/23-007r1.

History, Standards and Compilers

Next revision

MRCB treats templates as a future direction. Fortran 2028 is at committee draft stage with templates, generic subprograms and default kind in the working draft.

Generic and Rank Independent Programming

Source-form limits

MRCB’s source-form chapter gives the Fortran 2018 limits of 132 characters per line and 255 continuation lines. Fortran 2023 allows 10,000 characters per line, no limit on continuation lines and 1,000,000 characters per statement.

Program Structure and Source Form, Getting Started

Compiler support

MRCB has no compiler-support information, and its only compiler string is an old NAG release. The per-compiler table replaces that gap, and each page that shows a Fortran 2023 feature states what gfortran 16.2 and Flang 23 do.

History, Standards and Compilers

IEEE references

MRCB cites IEEE 754-2008 and ISO/IEC/IEEE 60559:2011. Fortran 2023 adopts ISO/IEC 60559:2020 (IEEE 754-2019): ieee_max, ieee_min, the _mag variants, the changed ieee_max_num family.

Floating-Point and IEEE Arithmetic

"Deprecated" features

MRCB’s Appendix A lists the authors' deprecations (include, double precision, do while, go to, the .eq. operators, implicit interfaces, sequence, non-default implicit, volatile, sync memory). They are advice, not entries in the standard’s obsolescent or deleted lists (Annex B); pages present them as recommendations. The Fortran 2028 draft adds default implicit typing and Dw.d to the real obsolescent list.

Best Practices and Style, Legacy Features and Modernization, Interfaces, Generics and Operator Overloading, Derived Types

err=, end=, eor=

Two footnotes of MRCB call err= obsolescent and point at Appendix A. They are not obsolescent in the standard (not in Annex B); iostat= with iomsg= is preferred style.

Input/Output: Units and Files, Internal Files, Namelist and Non-Advancing I/O

Recursion

Older text requires recursive to call a procedure from itself. Since Fortran 2018 a procedure is recursive by default and non_recursive says the opposite; gfortran 16.2 still diagnoses unmarked recursion, so write recursive for portability.

Procedures, Functions and Subroutines, Testing, Debugging and Profiling

Obsolete constructs in older material

forall is obsolescent since Fortran 2018 (use whole-array expressions, where or do concurrent); the arithmetic if, the nonblock do, real do variables, pause, assigned go to and the H descriptor are deleted. Real and double precision types as do variables are gone.

Control Flow, Legacy Features and Modernization

Kinds

Hard-coded kind numbers, real*8, double precision and 1.0d0 are compiler habits; use iso_fortran_env constants or selected_real_kind. real16, logical8 to logical64 and selected_logical_kind are Fortran 2023; kind values are processor dependent.

Intrinsic Types and Kinds, Intrinsic Modules and iso_fortran_env

Build tools

MRCB mentions only make and recompilation cascades. Today fpm, CMake and Meson find module dependencies and build order; Meson’s fortran_std stops at f2018.

Building with Make, CMake and Meson, Fortran Package Manager (fpm), Modules and Submodules

Compiler names and options

ifort was discontinued in oneAPI 2025.0 and replaced by ifx; flang-new was renamed flang in LLVM 20; -fbounds-check is a deprecated alias of -fcheck=bounds; the current standard level is -std=f2023.

Compilers and Compiler Options

Pointers instead of allocatables

Fortran 90 and 95 style pointer arrays and linked lists. Allocatable arrays, results and components (Fortran 2003 and 2008) and recursive allocatable components are safer and as fast.

Pointers and Targets, Allocatable Arrays and Dynamic Memory, Derived Types

Parallel features

Parallel Fortran described with forall, or with coarrays of Fortran 2008 only. Teams, events, collectives, atomics and failed images are Fortran 2018 (from TS 18508); put with notify and coarray components in arrays are Fortran 2023; GCC 16 has native shared-memory coarrays. OpenMP 6.0, OpenACC 3.4 and MPI 5.0 (mpi_f08) are the external models.

Coarrays, Images and Synchronization, Coarray Teams, Events, Collectives and Atomics, OpenMP and OpenACC, MPI with mpi_f08

C interoperability

The Fortran 2003 restrictions (no optional, allocatable or assumed-shape dummy arguments in a bind(c) interface) were lifted in Fortran 2018 through C descriptors; f_c_string, c_f_strpointer and c_f_pointer(lower=) are Fortran 2023; %VAL, hidden string lengths and integer*4 are compatibility mechanisms.

Interoperability with C, C Descriptors and ISO_Fortran_binding, Calling Fortran from C, C++ and Python

Python and f2py

f2py examples that use numpy.distutils and setup.py: NumPy 2.5 removed that backend and Meson is the only one.

Calling Fortran from C, C++ and Python

MATLAB (R2023a book, R2026b current)

mxGetPr/mxGetPi are not recommended since R2018b (use mex -R2018a and the typed accessors); the default build is still -R2017b; mexSetTrapFlag was removed (use mexCallMATLABWithTrap); mex builds free-form .F90 since R2026a; fixed-form .F files, integer*4/real*8, %VAL and pointer-sized integers in the book’s examples are compatibility styles.

MATLAB: MEX, Engine and MAT-File APIs

Libraries and tooling

Hand-written solvers, string and sorting helpers, external BLAS calls without interfaces, shell-script test runners: stdlib, stdlib_linalg, explicit interfaces, test-drive and fpm test are current. Documentation and editor tooling (FORD, fortls, fprettify) postdate the books.

Fortran stdlib, BLAS, LAPACK and Numerical Libraries, Testing, Debugging and Profiling, Documentation and Editor Tooling

Enumerations

MRCB’s "bind(c) enum" is called an interoperable enumeration in Fortran 2023 and can have a type name; the enumeration type is a language feature that neither gfortran 16.2 nor Flang 23 can run, so portable code uses enum, bind(c), as heatflow does.

Enumerations

Errata of the main reference book

The items below are slips in the printed book, recorded during the review of the book for this section. They are listed so that a reader who works from the book does not copy them, and each is described in my own words. The three that concern c_f_strpointer and the enumeration type statement (pages 452 to 454 and 462) were rechecked against J3/23-007r1 while writing this page, and the correct form given is the standard’s; the others were not independently rechecked here. The publisher keeps an errata file (edits.pdf) on the book’s web site; it could not be read from the tools used for this page (the publisher’s site returned no content), so this list is not a copy of it, and the file should be checked for items that this list does not contain. Page numbers are those of the printed book.

Page Problem and the correct form

1

The introduction says that only the last chapter covers Fortran 2023. The chapter on genericity (22) also contains Fortran 2023 material (typeof, classof, the rank clause, integer arrays as bounds and subscripts).

439

The figure with the generic-programming example declares one name for a diagonal and uses another, uses a data name that is not declared, and sizes a lower-bound array with the rank of a scalar. The rank of a scalar is 0, so that array has size zero; the intended declaration is probably an array whose size is the number of dimensions.

442

An ubound call passes an array section where the second argument belongs. The reference is ubound(a, rank(a)) (the array, then the dimension).

452

The pointer argument of c_f_strpointer is described as being of kind c_ptr. The standard (18.2.3.5) says it is a scalar deferred-length character pointer of kind c_char.

452-453

The length of the result is described inconsistently ("less than" in one place, "less than or equal to" in another) relative to nchars. The standard says the length is the largest value for which no null character appears in the sequence and which is less than or equal to nchars if present.

454

The getenv example calls c_f_pointer with a fixed count of 32768 characters. The standard’s own getenv example (18.2.3.5, case ii) uses c_f_strpointer, which finds the end of the string.

462

The general form of the enumeration type statement has unbalanced brackets and leaves type out of the end statement. The end statement is end enumeration type [name] (R769); the example on the same page is correct.

copyright page

The previous edition of the series is listed without a year; cite the book as the third edition of Modern Fortran Explained, 2023.

The fixed-form, real*8, integer*4, double precision, implicit typing, common, equivalence, go to, arithmetic if, statement-function, entry, forall and %VAL forms that appear in the reference books and in older material are not reproduced anywhere on the modern pages of this section; they appear only, and labelled as old code, on Legacy Features and Modernization.

Standard version provenance and compiler support

Item Introduced or stated by Support checked on 2026-10-19

The Fortran 2023 changes listed above

Fortran 2023 (Introduction of J3/23-007r1)

Varies by item; see the table. -std=f2023 in gfortran; Flang 23 -std= accepts only f2018 and implements part of the revision.

Conformance with ISO/IEC 60559:2020

Fortran 2023 (Foreword, Clause 17)

gfortran 16.2 lacks ieee_max, ieee_min and the _mag variants; Flang 23 has them.

Obsolescent list of twelve entries

Fortran 2023 (B.3)

Reported by -std=f2023 where the compiler checks; permitted otherwise.

Templates, generic subprograms, default kind, protected_target, pure/simple types, prefix reductions, new math functions, source-location procedures

Fortran 2028 working draft J3/26-007r1

Rejected by gfortran 16.2 (with -std=f2023 and -std=f202y) and Flang 23.

Default implicit typing and Dw.d obsolescent

Fortran 2028 working draft J3/26-007r1 (B.3.14, B.3.15)

Still accepted by both compilers.

Committee draft N2258

WG5

Not public; the ballot outcome is not published on the page read.

Compilers not installed for this page (Intel ifx, NAG, HPE Cray, NVIDIA HPC) are described by their own release notes on History, Standards and Compilers.

Pitfalls

  • Writing code against the draft. Nothing in J3/26-007r1 is implemented in either free compiler on the check date, and the draft still carries open technical issues. Use the Fortran 2023 techniques now and read the draft as a preview.

  • Calling the draft "the standard". It is a working document; the Committee Draft is not public and the standard is not published. Cite the clause numbers of J3/26-007r1 only with the draft’s date (3 March 2026).

  • Trusting -std=f202y to enable the draft. In gfortran 16.2 the switch enabled none of the items probed on this page; the manual calls the features it gates experimental.

  • Treating obsolescent as deleted, or the reverse. Obsolescent features (including forall, and from Fortran 2028 default implicit typing and Dw.d) still compile. The deleted features are the ones that -std=f2023 rejects.

  • Equating "the book says so" with "the standard says so". Appendix A of the main reference book is the authors' list. The standard’s lists are in Annex B.

  • Using a Fortran 2023 feature that only one compiler accepts. The table above shows the split; probe with both a compile and a run, because several rejections only appear at link or run time (tokenize and c_f_strpointer in gfortran 16.2).

  • Printing a conditional expression directly. gfortran 16.2 crashes on it; assign to a variable first.

  • Reading a status page as a promise. A compiler’s feature page, the fortran-lang compilers page and this page can lag or lead the compiler you installed; probe your own build.