NAG Fortran Compiler Release 7.2 Release Note
Table of Contents
- 1 Introduction
- 2 Release Overview
- 3 Compatibility
- 4 New Fortran 2018 Features
- 5 Fortran 2023 support
- 6 Additional OpenMP support
- 7 Additional error checking
- 8 Other enhancements
1 Introduction
Release 7.2 of the NAG Fortran Compiler is a major update.
Customers upgrading from a previous release of the NAG Fortran Compiler will need a new licence key for this release.
See KLICENCE.txt
for more information about Kusari Licence Management.
2 Release Overview
Release 7.2 supports all of Fortran 2018, and so the default language level is now -f2018.
Partial support for OpenMP 4.0 and 4.5 is included in the initial release of 7.2. An update will follow in early 2024 to upgrade that to full support.
3 Compatibility
3.1 Compatibility with Release 7.1
Release 7.2 is fully compatible with Release 7.1.3.2 Compatibility with Release 7.0
Release 7.2 is compatible with Release 7.0, except that files compiled with the -C=calls option will need to be recompiled if they contain a procedure with a procedure pointer argument, or a reference to such a procedure.3.3 Compatibility with Release 6.2
On MacOS the 32-bit ABI mode accessible via -abi=32 has been removed; consequently only 64-bit compilation is supported and the -abi= switch has been removed entirely.Other than this, Release 7.2 is fully compatible with Release 6.2 except when coarrays are used, or when the -C=calls option is used for a subroutine that has an alternate return. Any program that uses these features will need to be recompiled.
3.4 Compatibility with Release 6.1
Programs which use features from HPF (High Performance Fortran), for example theILEN
intrinsic function or the HPF_LIBRARY
module, are no
longer supported.
The previously deprecated -abi=64 option on Linux x86-64 has been withdrawn. This option provided an ABI with 64-bit pointers but 32-bit object sizes and subscript arithmetic, and was only present for compatibility with Release 5.1 and earlier.
With the exception of HPF support and the deprecated option removal, Release 7.2 of the NAG Fortran Compiler is fully compatible with Release 6.1.
3.5 Compatibility with Release 6.0
With the exception of HPF support and the deprecated option removal, Release 7.2 of the NAG Fortran Compiler is compatible with Release 6.0 except that programs that use allocatable arrays of “Parameterised Derived Type” will need to be recompiled (this only affects module variables and dummy arguments).3.6 Compatibility with Releases 5.3.1, 5.3 and 5.2
With the exception of HPF support and the deprecated option removal, Release 7.2 of the NAG Fortran Compiler is fully compatible with Release 5.3.1. It is also fully compatible with Releases 5.3 and 5.2, except that on Windows, modules or procedures whose names begin with a dollar sign ($) need to be recompiled.For a program that uses the new “Parameterised Derived Types” feature, it is strongly recommended that all parts of the program that may allocate, deallocate, initialise or copy a polymorphic variable whose dynamic type might be a parameterised derived type, should be compiled with Release 7.1 or later.
3.7 Compatibility with Release 5.1
Release 7.2 of the NAG Fortran Compiler is compatible with NAGWare f95 Release 5.1 except that:- programs that use features from HPF are not supported;
-
programs or libraries that use the
CLASS
keyword, or which contain types that will be extended, need to be recompiled; - 64-bit programs and libraries compiled with Release 5.1 on Linux x86-64 (product NPL6A51NA) are binary incompatible, and need to be recompiled.
4 New Fortran 2018 Features
-
The
GENERIC
statement provides a concise way of declaring generic interfaces. It has the syntax:GENERIC
[ , access-spec ]::
generic-spec=>
procedure-name-listPUBLIC
orPRIVATE
, the generic-spec is a generic identifier (name,ASSIGNMENT(=)
,OPERATOR(
op)
, or {READ
|WRITE
}(
{FORMATTED
|UNFORMATTED
})
), and the procedure-name-list is a comma-separated list of named procedures.The access-spec is only permitted if the
GENERIC
statement is in the specification part of a module. Each named procedure in the list must have an explicit interface; that is, it must be an internal procedure, module procedure, or be declared with an interface block or procedure declaration statement that specifies an explicit interface. Collectively, the procedures must satisfy the usual generic rules about all being functions or all being subroutines, and being unambiguous.Apart from the optional access-spec, the
GENERIC
statement has the same effect asINTERFACE generic-spec PROCEDURE procedure-name-list END INTERFACE
The only advantage is that it is a couple of lines shorter, and can declare the accessibility in the same line. This syntax is the same as for a generic-binding in a derived type definition, except that the list of names is of ordinary named procedures instead of type-bound procedures.For example, the program
Module print_sqrt Private Generic,Public :: g => s1, s2 Contains Subroutine s1(x) Print '(F10.6)',Sqrt(x) End Subroutine Subroutine s2(n) Print '(I10)',Nint(Sqrt(Real(n))) End Subroutine End Module Program test Use print_sqrt Call g(2.0) Call g(127) End Program
will print1.414214 11
-
The
E0
exponent width specifier can be used on all edit descriptors that allow the exponent width to be specified (thusE
,EN
et al, but notD
). This specifies formatting with the minimal width for the exponent. For example,Print '(7X,3ES10.2E0)', 1.23, 4.56E24, 7.89D101
will print1.23E+0 4.56E+24 7.89E+101
-
The
E
,D
,EN
andES
edit descriptors may have a width of zero on output. This provides minimal width editing similarly to theI
and other edit descriptors; that is, the processor chooses the smallest value for the width w that does not result in the field being filled with asterisks. This means that leading blanks will be suppressed, and forE
andD
, when the scale factor is less than or equal to zero, the optional zero before the decimal symbol is suppressed.For example, printing 12.3 with the formats shown below will display the results below with no leading or trailing blanks.
E0.4
.1230E+02
E0.4E3
.1230E+002
1PE0.4
1.2300E+00
EN0.4
12.3000E+00
ES0.4
1.2300E+01
E0.4E0
.1230E+2
Note that field width has no effect on the format of the exponent; that is, to print a number in the smallest width requires use of exponent width zero as well (as shown in the last example above).
There is no means of eliminating trailing zeroes in the mantissa part for these edit descriptors (though there is for the new
EX
edit descriptor). -
The
G0.d
edit descriptor is permitted for types Integer, Logical, and Character; in Fortran 2008, this was an i/o error. In Fortran 2018 it has the same effect asI0
for Integer,L1
for Logical, andA
for Character. For example,Print '(7X,"start:",3G0.17,":end")', 123, .True., 'ok'
will printstart:123Tok:end
-
The new edit descriptors
EXw.d
andEXw.dEe
can be used for output of floating-point numbers with a hexadecimal significand. The format is[ s ]
where s is an optional plus or minus sign (+ or −), each xi is a hexadecimal digit (0X
x0.
x1x2… exponent0
…9
orA
…F
), and exponent is the binary exponent (power of two) expressed in decimal, with the formatP
s z1…zn, where if the optionalE
e appears, n is equal to e, and otherwise is the minimum number of digits needed to represent the exponent. If the exponent is equal to zero, the sign s is a plus sign.If the number of digits d is zero, the number of mantissa digits xi produced is the smallest number that represents the internal value exactly. Note that d must not be zero if the radix of the internal value is not a power of two.
For input, the effect of the
EX
edit descriptor is identical to that of theF
edit descriptor.Note that the value of the initial hexadecimal digit is not standardised, apart from being non-zero. Thus, depending on the compiler, writing the value 1.0 in
EX0.1
might produce0X1.0P+0
,0X2.0P-1
,0X4.0P-2
, or0X8.0P-3
. The NAG Fortran Compiler always shifts the mantissa so that the most significant bit is set, thus will output0X8.0P-3
in this case. -
Input of floating-point numbers with list-directed, namelist, and explicit formatting (e.g. the
F
edit descriptor) accepts input values in hexadecimal-significand form. That is, the form produced by theEX
edit descriptor. Note that a hexadecimal-significand value always begins with an optional sign followed by the digit zero and the letterX
; that is,+0X
,-0X
, or0X
, thus there is no ambiguity.For example, reading ‘
-0XA.P-3
’ will produce the value-1.25
.As usual for numeric input, lowercase input is treated the same as upper case; thus
-0xa.p-3
produces the same value as-0XA.P-3
. -
The elemental intrinsic function
OUT_OF_RANGE
returns true if and only if a conversion would be out of range. It has the syntax:OUT_OF_RANGE ( X, MOLD [ , ROUND ] )
X
: type Real or Integer;MOLD
: scalar of type Real or Integer;ROUND
(optional) : scalar of type Logical;Result : Logical of default kind.
The result is true if and only if the value of
X
is outside the range of values that can be converted to the type and kind ofMOLD
without error. If theMOLD
argument is a variable, it need not have a defined value — only its type and kind are used. TheROUND
argument is only allowed whenX
is type Real andMOLD
is type Integer.For Real to Integer conversions, the default check is whether the value would be out of range for the intrinsic function
INT (X, KIND (MOLD))
; this is the same conversion that is used in intrinsic assignment. If theROUND
argument is present with the value.TRUE.
, the check is instead whether the value would be out of range for the intrinsic functionNINT (X, KIND (MOLD))
.For example,
OUT_OF_RANGE (127.5, 0_int8)
is false, butOUT_OF_RANGE (127.5, 0_int8, .TRUE.)
is true.If the value of
X
is an IEEE infinity,OUT_OF_RANGE
will return.TRUE.
if and only if the type and kind ofMOLD
does not support IEEE infinities. Similarly, ifX
is an IEEE NaN, the result is true if and only ifMOLD
does not support IEEE NaNs.Note that when checking conversions of type Real of one kind to type Real of another kind (for example,
REAL(real32)
toREAL(real16)
orREAL(real64)
toREAL(real32)
), a finite value that is greater thanHUGE (KIND (MOLD))
will be considered out of range, but an infinite value will not be considered out of range. That is,OUT_OF_RANGE (1.0E200_real64, 1.0_real32)
will return.TRUE.
, butOUT_OF_RANGE (IEEE_VALUE (1.0_real64, IEEE_POSITIVE_INF), 1.0_real32)
will return.FALSE.
.Although this function is elemental, and can be used in constant expressions (if the value of
X
is constant and theROUND
argument is missing or constant), only theX
argument is permitted to be an array. The result thus always has the rank and shape ofX
. -
The
VALUES
argument of the intrinsic subroutineDATE_AND_TIME
can be any kind of integer with a decimal exponent range of at least four; that is, any kind except 8-bit integer. For example,Program show_year Use Iso_Fortran_Env Integer(int16) v(8) Call Date_And_Time(Values=v) Print *,'The year is',v(1) End Program
-
The
WAIT
argument of the intrinsic subroutineEXECUTE_COMMAND_LINE
can be any kind of logical. TheCMDSTAT
andEXITSTAT
arguments can be any kind of integer with a decimal exponent range of at least four; that is, any kind except 8-bit integer. For example,Program ok Use Iso_Fortran_Env Logical(logical8) :: w = .True._logical8 Integer(int16) :: cstat Integer(int64) :: estat Call Execute_Command_Line('echo ok',w,estat,cstat) If (estat/=0 .Or. cstat/=0) Print *,'Bad STAT',estat,cstat End Program
will, assuming ‘echo
’ is the Unix echo command, displayok
-
The intrinsic subroutines
GET_COMMAND
,GET_COMMAND_ARGUMENT
andGET_ENVIRONMENT_VARIABLE
now have an optionalERRMSG
argument at the end of the argument list. If an error occurs (i.e., a positive value would be assigned to theSTATUS
argument), theERRMSG
argument will be assigned an explanatory message. If no error occurs (zero or a negative value would be assigned to theSTATUS
argument), theERRMSG
argument remains unchanged. Note that the effect on theERRMSG
argument occurs (or does not occur) even if theSTATUS
argument is omitted. But as it is unchanged when no error occurs, it is not a substitute for theSTATUS
argument for detecting errors.For example, executing this program
Program test Character(200) msg,value Integer status Call Get_Environment_Variable('Does Not Exist',value,status,Errmsg=msg) If (status>0) Print *,Trim(msg) End Program
will, unless there is an environment variable called ‘Does Not Exist
’, print something likeEnvironment variable does not exist
-
The intrinsic function
IMAGE_INDEX
has two additional forms:IMAGE_INDEX( COARRAY, SUB, TEAM ) IMAGE_INDEX( COARRAY, SUB, TEAM_NUMBER )
TEAM
: scalar of typeTEAM_TYPE
,Intent(In)
;
TEAM_NUMBER
: scalar of type Integer,Intent(In)
.COARRAY
andSUB
arguments are unchanged, except that the subscripts are interpreted as being for the specified team. The return value is likewise the image index in the specified team. -
The random-number generator (intrinsic
RANDOM_NUMBER
) is now per-image. Fortran 2008 permitted a compiler to use a single random-number stream, shared between all images; Fortran 2018 does not permit that, instead requiring each image to have its own random-number state. -
The new intrinsic subroutine
RANDOM_INIT
initialises the random-number generator on the invoking image. It has the syntax:CALL RANDOM_INIT ( REPEATABLE, IMAGE_DISTINCT )
REPEATABLE
: scalar of type Logical,Intent(In)
;
IMAGE_DISTINCT
: scalar of type Logical,Intent(In)
.If
IMAGE_DISTINCT
is true, the initial state (seed) of the random-number generator will be different on every invoking image; otherwise, the initial state will not depend on which image it is. IfREPEATABLE
is true, each execution of the program will use the same initial seed (image-dependent ifIMAGE_DISTINCT
is also true); otherwise, each execution of the program will use a different initial seed.The default for the NAG Fortran Compiler, when no call to
RANDOM_INIT
is made, isREPEATABLE=
false andIMAGE_DISTINCT=
true. -
There are additional constants, types, and procedures in the standard intrinsic module
IEEE_ARITHMETIC
, providing additional support for IEEE (ISO/IEC 60559) arithmetic. Three of the pre-existing procedures now have additional, optional, arguments.-
The named constant
IEEE_AWAY
is of typeIEEE_ROUND_TYPE
, and represents a rounding mode that rounds ties away from zero. The IEEE standard only requires this rounding mode for decimal, and binary hardware does not support this, so it cannot be used. -
The elemental function
IEEE_FMA
performs a fused multiply-add operation. It has the syntax:IEEE_FMA (A, B, C)
A
: type Real;
B
: same type and kind asA
;
C
: same type and kind asA
.Result : Same type and kind as
A
.The result of the function is the value of (
A
×B
)+C
with only one rounding; that is, the whole operation is computed mathematically and only rounded to the format ofA
at the end. For example,IEEE_OVERFLOW
is not signalled ifA
×B
overflows, but only if the final result is out of range.Restriction: this function must not be invoked when the kind of
A
is not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (A)
returns false. -
The pure subroutine
IEEE_GET_MODES
retrieves the halting modes, rounding modes, and underflow mode in a single object. Its syntax is:IEEE_GET_MODES (MODES)
MODES
: scalar of typeIEEE_MODES_TYPE
,Intent(Out)
.IEEE_SET_MODES
to restore the modes. -
The pure subroutine
IEEE_GET_ROUNDING_MODE
, which retrieves the current rounding mode, now has an optional argument to specify the radix. The syntax is thus now:IEEE_GET_ROUNDING_MODE (ROUND_VALUE [, RADIX ])
ROUND_VALUE
: typeIEEE_ROUND_TYPE
,Intent(Out)
;
RADIX
(optional) : Integer,Intent(In)
, must be equal to two or ten.The
ROUND_VALUE
argument is assigned the current rounding mode for the specified radix. IfRADIX
does not appear, the binary rounding mode is assigned. -
The elemental function
IEEE_INT
converts an IEEE Real value to Integer with a specific rounding mode. It has the syntax:IEEE_INT (A, ROUND [, KIND ])
A
: type Real;
ROUND
: typeIEEE_ROUND_TYPE
;
KIND
(optional) : scalar Integer constant expression;
Result : type Integer, with kindKIND
ifKIND
appears, otherwise default kind.The value of
A
is rounded to an integer using the rounding mode specified byROUND
. If that value is representable in the result kind, the result has that value; otherwise, the result is processor-dependent andIEEE_INVALID
is signalled.This operation is either the
convertToInteger{round}
or theconvertToIntegerExact{round}
operation specified by the IEEE standard. If it is the latter, andIEEE_INVALID
was not signalled, butA
was not already an integer,IEEE_INEXACT
is signalled.Restriction: this function must not be invoked when the kind of
A
is not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (A)
returns false. -
The elemental functions
IEEE_MAX_NUM
,IEEE_MAX_NUM_MAG
,IEEE_MIN_NUM
,IEEE_MIN_NUM_MAG
perform maximum/minimum operations ignoring NaN values. If an argument is a signalling NaN,IEEE_INVALID
is raised, if only one argument is a NaN, the result is the other argument; only if both arguments are NaNs is the result a NaN. The syntax forIEEE_MAX_NUM
is:IEEE_MAX_NUM (X, Y)
X
: type Real;
Y
: same type and kind asX
;
Result : same type and kind asX
.X
andY
, ignoring NaN.Restriction: this function must not be invoked when the kind of
X
is not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (X)
returns false.The
IEEE_MAX_NUM_MAG
has the same syntax (apart from the name), and the result is whichever ofX
andY
has the greater magnitude. The same restriction applies.The
IEEE_MIN_NUM
has the same syntax (apart from the name), and the result is the minimum value ofX
andY
, ignoring NaN. The same restriction applies.The
IEEE_MIN_NUM_MAG
has the same syntax (apart from the name), and the result is whichever ofX
andY
has the smaller magnitude. The same restriction applies. -
The derived type
IEEE_MODES_TYPE
contains the all the floating-point modes: the halting modes, the rounding modes, and the underflow mode. It is used by theIEEE_GET_MODES
andIEEE_SET_MODES
subroutines. -
The elemental functions
IEEE_QUIET_
{EQ
|NE
|LT
|LE
|GT
|GE
} compare two IEEE format numbers, without raising any signal if an operand is a quiet NaN. If an operand is a signalling NaN, theIEEE_INVALID
exception is raised.IEEE_QUIET_EQ
andIEEE_QUIET_NE
are exactly the same as==
and/=
, apart from only being usable on IEEE format numbers. TheIEEE_QUIET_EQ
function has the syntax:IEEE_QUIET_EQ (A, B)
A
: type Real (any IEEE kind);
B
: same type and kind asA
;Result : Logical of default kind.
The syntax of
IEEE_QUIET_NE
et al is the same, except for the name of the function.Restriction: these functions must not be invoked when the kind of X is not an IEEE format, i.e. if
IEEE_SUPPORT_DATATYPE (X)
returns false. -
The elemental function
IEEE_REAL
converts an Integer or IEEE format Real value to the specified IEEE format Real value. Its syntax is:IEEE_REAL (A, [, KIND ])
A
: type Real or Integer;
KIND
(optional) : scalar Integer constant expression;
Result : type Real, with kindKIND
ifKIND
appears, otherwise default kind.A
is representable in the kind of the result, that value is the result. Otherwise, the value ofA
is rounded to the kind of the result using the current rounding mode.Restriction: this function must not be invoked when the kind of
A
or the result is not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (A)
or ifIEEE_SUPPORT_DATATYPE(REAL(0,KIND))
returns false. -
The pure subroutine
IEEE_SET_MODES
sets the halting modes, rounding modes, and underflow mode to the state when a previous call toIEEE_GET_MODES
was made. Its syntax is:IEEE_SET_MODES (MODES)
MODES
: scalar of typeIEEE_MODES_TYPE
,Intent(In)
.MODES
must be one that was obtained viaIEEE_GET_MODES
. -
The pure subroutine
IEEE_SET_ROUNDING_MODE
, which sets the rounding mode, now has an optional argument to specify the radix. The syntax is thus now:IEEE_SET_ROUNDING_MODE (ROUND_VALUE [, RADIX ])
ROUND_VALUE
: typeIEEE_ROUND_TYPE
,Intent(In)
;
RADIX
(optional) : Integer,Intent(In)
, must be equal to two or ten.The rounding mode for the specified radix is set to
ROUND_VALUE
. IfRADIX
does not appear, the binary rounding mode is set.Restriction: This subroutine must not be invoked unless there is some
X
(with radixRADIX
if it is present) for which bothIEEE_SUPPORT_DATATYPE(X)
andIEEE_SUPPORT_ROUNDING(ROUND_VALUE,X)
are true. -
The elemental functions
IEEE_SIGNALING_
{EQ
|NE
|LT
|LE
|GT
|GE
} compare two IEEE format numbers, raising theIEEE_INVALID
exception if an operand is a NaN (whether quiet or signalling).IEEE_SIGNALING_LT
,IEEE_SIGNALING_LE
,IEEE_SIGNALING_GT
andIEEE_SIGNALING_GE
are exactly the same as<
,<=
,>
and>=
, apart from only being usable on IEEE format numbers. TheIEEE_SIGNALING_EQ
function has the syntax:IEEE_SIGNALING_EQ (A, B)
A
: type Real (any IEEE kind);
B
: same type and kind asA
;Result : Logical of default kind.
The syntax of
IEEE_SIGNALING_NE
et al is the same, except for the name of the function.Restriction: these functions must not be invoked when the kind of X is not an IEEE format, i.e. if
IEEE_SUPPORT_DATATYPE (X)
returns false. -
The elemental function
IEEE_SIGNBIT
queries the sign bit of an IEEE format number. It has the syntax:IEEE_SIGNBIT (X)
X
: type Real (any IEEE kind);Result : Logical of default kind.
The result is true if and only if the sign bit is set (indicating negative for any value that is not a NaN).
Restriction: this function must not be invoked when the kind of
X
is not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (X)
returns false. -
The elemental function
IEEE_RINT
now has an optional argument to specify the rounding required. The syntax is thus now:IEEE_RINT (X [, ROUND ])
X
: type Real;
ROUND
(optional) : typeIEEE_ROUND_TYPE
.Result : Same type and kind as
X
.When
ROUND
is present, the result is the value ofX
rounded to an integer according to the mode specified byROUND
; this is the operation the IEEE standard callsroundToIntegral{rounding}
. WhenROUND
is absent, the result is the value ofX
rounded to an integer according to the current rounding mode; this is the operation the IEEE standard callsroundToIntegralExact
.Restriction: this function must not be invoked when the kind of
X
is not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (X)
returns false.
-
The named constant
-
The named constant
C_PTRDIFF_T
has been added to the intrinsic moduleISO_C_BINDING
. This is the integer kind that corresponds to the C typeptrdiff_t
, which is an integer large enough to hold the difference between two pointers. For example, the interfaceInterface Function diff_cptr(a,b) Bind(C) Use Iso_C_Binding Type(C_ptr),Value :: a, b Integer(C_ptrdiff_t) diff_cptr End Function End Interface
interoperates with the C functionptrdiff_t diff_cptr(void *a,void *b) { return a - b; }
-
In the intrinsic module
ISO_C_BINDING
, the proceduresC_LOC
andC_FUNLOC
are considered to be pure procedures, andC_F_POINTER
andC_F_PROCPOINTER
are considered to be impure. When it is used within a pure procedure, the argument ofC_FUNLOC
must also be a pure procedure. -
The default accessibility in a module of entities accessed from another module (via the
USE
statement) can be controlled by specifying that module name in aPUBLIC
orPRIVATE
statement, overriding the default accessibility of other entities in the importing module. For example, inModule mymod Use Iso_Fortran_Env Real(real32) x Integer(int64) y Private Iso_Fortran_Env End Module
all the entities inISO_FORTRAN_ENV
are by defaultPRIVATE
in modulemymod
, without needing to list them individually.This new default accessibility can be overridden by an explicit
PUBLIC
orPRIVATE
declaration. Also, if an entity in a remote module (two or moreUSE
statements away) is accessed by more than one intervening module, it is defaultPRIVATE
only if every route to the entity is defaultPRIVATE
, and defaultPUBLIC
if any route is defaultPUBLIC
. For example, inModule remote Real a,b End Module Module route_one Use remote Private remote End Module Module route_two Use remote End Module Module my_module Use route_one Use route_two Private route_one End Module
the variables
A
andB
in moduleREMOTE
arePUBLIC
in moduleMY_MODULE
, because they are accessible via moduleROUTE_TWO
which is defaultPUBLIC
. -
The
IMPLICIT NONE
statement can now haveTYPE
andEXTERNAL
specifiers. Its full syntax is now:IMPLICIT NONE
[(
[ implicit-none-specifier-list ])
]EXTERNAL
andTYPE
. No keyword may appear more than once in the list. If the list does not appear, or ifTYPE
appears in the list, no otherIMPLICIT
statement may appear in the scoping unit.The semantics of:
IMPLICIT NONE ()
IMPLICIT NONE (TYPE)
IMPLICIT NONE
If the keyword
EXTERNAL
appears, a procedure with an implicit interface that is referenced in the scoping unit must be given theEXTERNAL
attribute explicitly: that is, it must be declared in anEXTERNAL
statement, in a type declaration statement that has theEXTERNAL
attribute, or in a procedure declaration statement. For example,Subroutine sub(x) Implicit None (External) Integer f Print *,f(x) End Subroutine
will produce an error for the reference to the functionF
, because it does not have theEXTERNAL
attribute.If the keyword
EXTERNAL
appears and the keywordTYPE
does not appear, implicit typing is not disabled, and otherIMPLICIT
statements may appear in the scoping unit. If both the keywordsTYPE
andEXTERNAL
appear, both implicit typing is disabled, and theEXTERNAL
attribute is required for implicit-interface procedures. -
The
IMPORT
statement can appear inBLOCK
constructs and nested subprograms. By default, such scoping units have access to all entities in the host scope by host association, so by itself this is only useful as (compiler-checked) documentation. For example,Subroutine outer(x,y) Real,Intent(InOut) :: x, y(:) … Contains Subroutine inner Import :: x, y …
-
Control over host association is provided by the
IMPORT,NONE
,IMPORT,ALL
, andIMPORT,ONLY
statements. Like otherIMPORT
statements, they can appear only in interface bodies,BLOCK
constructs, and contained subprograms, and appear in betweenUSE
statements and other specification statements.The
IMPORT,NONE
statement specifies that no entities in the host scope are accessible by host association. That is the default for interface bodies other than separate module procedure interfaces. If anIMPORT,NONE
statement appears in a scoping unit, no otherIMPORT
statement may appear. For example, inSubroutine outer(x,y) Real,Intent(InOut) :: x, y(:) … Contains Subroutine inner Import,None Implicit Integer (a-z) Read *,x Print *,x End Subroutine End Subroutine
theX
in subroutineINNER
is not a reference to theX
in its hostOUTER
, but is an implicitly typed (Integer
) variable that is local toINNER
.The
IMPORT,ALL
statement specifies that all host entities are accessed. That means that a declaration which would otherwise make a host entity inaccessible (so-called “shadowing”), is invalid. For example, inSubroutine outer(x,y) Real,Intent(InOut) :: x, y(:) … Contains Subroutine inner Import,All Integer,External :: y …
the declaration ofY
insideINNER
is invalid, and will produce a compilation error. If anIMPORT,ALL
statement appears in a scoping unit, no otherIMPORT
statement may appear.The
IMPORT,ONLY
statement specifies that only host entities named inIMPORT,ONLY
statements are accessible by host association. If anIMPORT,ONLY
statement appears in a scoping unit, all otherIMPORT
statements must have theONLY
keyword. For example, inSubroutine outer(x,y,z) Real,Intent(InOut) :: x, y(:),z … Contains Subroutine inner Import,Only:x,y z = x + y
the references toX
andY
inINNER
are references to the host (OUTER
) entities, but the reference toZ
inINNER
is to an implicitly-typed local variable. -
An implied
DO
loop in an array constructor, or in aDATA
statement, may now have an Integer type-spec preceding the loop control. The syntax for such a loop in the array constructor is(
ac-value-list,
integer-type-spec::
ac-do-variable=
from,
to [,
step ])
DATA
statement is(
data-i-do-object-list,
integer-type-spec::
data-i-do-variable=
from,
to [,
step ])
INTEGER
.The effect is that inside the loop, the implied-
DO
variable (ac-do-variable or data-i-do-variable) has the type and kind specified by the integer-type-spec, regardless of the type and kind it might have outside the loop.Note that if there is an entity with the same name in the scope containing the loop, it must be a scalar variable; for example, it cannot be a procedure or type name.
For example,
Real x Print *, [ (x, Integer :: x = 1, 10) ]
is valid, and results in the output of the integer values 1 to 10. Similarly,Real x, y(10) Data (y(x),Integer::x=1,10,2) / 5*0 /
is valid, and initialises the odd-numbered elements ofY
to zero.This is mostly useful when subscripts may exceed the range of default integer kind, for example,
Real,Pointer :: a(:) ... Print *, [ (f(a(i)), Integer(int64) :: i = Lbound(a,1,int64), Ubound(a,1,int64)) ]
will apply functionF
to each element ofA
, even if the bounds are, for example 20000000000:20000000005. -
The
DO CONCURRENT
construct can have locality specifiersLOCAL
,LOCAL_INIT
, andSHARED
. These locality specifiers determine how a variable can be used within and without the loop, and cannot be applied to the loop index variables, which are always effectivelyLOCAL
. There is also aDEFAULT(NONE)
locality specifier, which requires all variables used inDO CONCURRENT
to be given an explicit locality. The revised syntax of theDO CONCURRENT
statement, ignoring labels and construct names, is:DO CONCURRENT
concurrent-header [ locality-spec ]...LOCAL (
variable-name-list)
LOCAL_INIT (
variable-name-list)
SHARED (
variable-name-list)
DEFAULT (NONE)
LOCAL
orLOCAL_INIT
specifier must be a rather ordinary variable: it must not have theALLOCATABLE
orOPTIONAL
attribute, must not have an allocatable ultimate component, and must not be a coarray or an assumed-size array. If it is polymorphic, it must have thePOINTER
attribute. Finally, it must be permitted to appear in a variable definition context: for example, it cannot beINTENT(IN)
. The effect ofLOCAL
andLOCAL_INIT
is that the variable inside the construct is completely separate from the one outside the construct; ifLOCAL
, it begins each iteration undefined, and ifLOCAL_INIT
, it begins each iteration with the value of the outside variable. This ensures thatLOCAL
andLOCAL_INIT
variables cannot cause any dependency between iterations.A variable that is
SHARED
is the same variable inside the construct as outside. If it is given a value by any iteration, it must not be referenced or given a value by any other iteration. If it is allocatable or a pointer, it similarly must only be allocated, deallocated, or pointer-assigned by a single iteration. If a discontiguous array isSHARED
, it must not be passed as an actual argument to a contiguous dummy argument (i.e. the dummy must be assumed-shape or a pointer, and must not have theCONTIGUOUS
attribute).Providing locality specifiers for variables in a
DO CONCURRENT
construct not only improves the readability of the code, but makes it easier for the compiler to parallelise the loop, perhaps with a suitable compiler option. (At Release 7.2, the NAG Fortran Compiler has no such option.) -
The arithmetic
IF
statement is treated as a Deleted feature. (This is because the behaviour when the expression is an IEEE NaN is undefined, and can have no good definition.) For example, if the filedel.f90
containsSubroutine sub(x) Real,Intent(In) :: x If (x) 1,2,3 1 Stop 1 2 Stop 2 3 Stop 3 End Subroutine
this warning message will be produced:Deleted feature used: del.f90, line 3: Arithmetic IF statement
If the -Error=Deleted option is used, this will be treated as an error. -
The
DO
construct with a label is considered to be Obsolescent (it is effectively replaced by theEND DO
statement and construct labels). Furthermore, the non-blockDO
construct is treated as a Deleted feature. A non-blockDO
is either two or more nestedDO
loops with a sharedDO
termination label, or aDO
loop with a terminating statement other thanEND DO
orCONTINUE
. (This is because these are hard to understand, error-prone, and better functionality has been available via the blockDO
construct since Fortran 90.) For example, if the fileobsdel.f90
containsSubroutine sub(w,x,y) Real,Intent(InOut) :: w(:),x(:,:), y(:) Integer i,j Do 100 i=1,Size(w) w(i) = w(i)**2 + 4*w(i) - 4 100 Continue Do 200 j=1,Size(x,2) Do 200 i=1,Size(x,1) If (x(i,j)<0) Go To 200 x(i,j) = Sqrt(x(i,j)+1) 200 Continue Do 300 i=1,Size(y) If (y(i)<0) Go To 300 y(i) = Log(y(i)) 300 Print *,y(i) End Subroutine
these warning messages will be produced:Obsolescent: obsdel.f90, line 4: DO statement with label (100) Obsolescent: obsdel.f90, line 7: DO statement with label (200) Obsolescent: obsdel.f90, line 8: DO statement with label (200) Deleted feature used: obsdel.f90, line 11: 200 is a shared DO termination label Obsolescent: obsdel.f90, line 12: DO statement with label (300) Deleted feature used: obsdel.f90, line 15: DO 300 ends neither with CONTINUE nor ENDDO
-
The
FORALL
statement and construct are considered to be Obsolescent. This is because it usually has worse performance than ordinaryDO
orDO CONCURRENT
. For example, if the fileobs.f90
containsSubroutine sub(a,b,c) Real,Intent(InOut) :: a(:) Real,Intent(In) :: b(:),c Integer i Forall(i=1:Size(a)) a(i) = b(i)**2 - c End Forall End Subroutine
this warning message will be produced:Obsolescent: obs.f90, line 5: FORALL construct
-
If the Fortran language level is 2018 or higher (the default), extension messages are produced for the
use of non-standard intrinsic modules such as
F90_KIND
orOMP_LIB
.
5 Fortran 2023 support
The NAG Fortran compiler supports the features from the recently revised and published Fortran 2023 standard that are listed below.
- A line in free source form can be up to 10000 (ten thousand) characters long. If the -f2023 option was not used, an extension message will be produced for any line longer than 132 characters. (The NAG Fortran compiler continues to accept lines of any length, but lines longer than 10000 characters are reported as a NAG extension, not a Fortran 2023 extension.)
-
The intrinsic inquiry function
SELECTED_LOGICAL_KIND
returns the kind value for a specified size of Logical. It has the following syntax:SELECTED_LOGICAL_KIND ( BITS )
BITS
: scalar Integer;Result : scalar Integer of default kind.
The result is the kind type parameter value for type Logical that specifies a kind whose size is at least
BITS
bits; ifBITS
is greater than the storage size of the largest kind of Logical, the result is −1. Thus any value ofBITS
less than or equal to eight will return the kind of a single-byte Logical (as all known compilers support single-byte Logical). With the NAG Fortran compiler, the result will be −1 ifBITS
is greater than 64, as its largest supported Logical kind has 64 bits. -
The standard intrinsic module
ISO_FORTRAN_ENV
contains additional named constants, supplying the kind type parameter values for Logical kinds with the indicated bit sizes:LOGICAL8
,LOGICAL16
,LOGICAL32
andLOGICAL64
. If there is no kind of Logical whose storage size is exactly the size indicated, the constant has the value −1. -
The
AT
edit descriptor can be used for output of character data. The character data are output with trailing blanks omitted, as if each element of the output item were surrounded with a call to the intrinsic functionTRIM
.For example,
Character(100) :: a(3) a(1) = 'o' a(2) = 'ka' a(3) = 'y' Print '(8X,3AT)', a
will display the lineokay
with no trailing blanks.The
AT
edit descriptor is not allowed for input (READ
statements).
6 Additional OpenMP support
OpenMP 4.0 and 4.5 are partially supported at this time.
This includes the SIMD
and TARGET
constructs, including DO SIMD
and TARGET DATA
,
and clauses such as the LINEAR
clause.
A forthcoming update will complete the support of OpenMP 4.0 and 4.5.
7 Additional error checking
-
A warning message is issued if the field width in an edit descriptor, either in a
FORMAT
statement or in a constant character string used as a format, might be too small for output of some values. For example, the programProgram na Read *,x Print 100,x 100 Format('X has the value ',E9.3) End Program
will produce the warning messageWarning: na.f90, line 4: In E9.3 the width 9 may be too small for output of some numbers
If the field width is too small for output of any finite number (an IEEE NaN only needs a width of three), the message will say that, e.g. if we changeE9.3
in the example toE9.7
, it will produce the warningWarning: na.f90, line 4: Field width too small for output of finite numbers - the E9.7 edit descriptor will produce all asterisks
and if the field width is less than three, the message is again changed, e.g. forE2.1
, the warning isWarning: na.f90, line 4: Field width of 2 for the E edit descriptor will inevitably produce all asterisks as output
-
Appearance of the
REC=
orPOS=
specifiers with the default unit, e.g. withUNIT=*
, is detected as an error at compile time. That unit is a sequential formatted unit, and those specifiers cannot be used with sequential input/output. For example, compilingProgram badio Write(*,'(A)',Rec=999) 'Oops' End Program
produces the errorError: badio.f90, line 2: REC= and UNIT=* are not compatible
-
Calling a procedure with an implicit interface, when that procedure appears elsewhere in the
file and is elemental, is detected as an error at compile time.
For example, compiling
Program c Real a(10) Call d(a,1.0) Print *,a End Program Elemental Subroutine d(x,y) Real,Intent(Out) :: x Real,Intent(In) :: y x = y End Subroutine
produces the errorError: c.f90: Explicit interface required for ELEMENTAL procedure D referenced from C
-
The most obvious cases of modifying an active team variable in a
CHANGE TEAM
construct are detected as an error at compile time. The Fortran standard prohibits such changes, to allow a compiler to use the active team variable throughout the construct without any need to make a copy of its data. For example, compilingSubroutine teamswap(team1,team2) Use Iso_Fortran_Env Type(team_type),Intent(InOut) :: team1,team2 Type(team_type) tmp Change Team (team2) tmp = team1 ! Okay. team1 = team2 ! Okay. team2 = tmp ! BAD End Team End Subroutine
produces the error messageError: teamswap.f90, line 8: Variable TEAM2 on left-hand side of assignment statement is the active team value for the CHANGE TEAM statement at line 5 of teamswap.f90
8 Other enhancements
-
The low-order bits in double precision and quad precision
RANDOM_NUMBER
now have complete entropy. In previous releases, although the number sequence had complete entropy, the low-order bits (21 bits in double precision, and 53 bits in quad precision) were not random. (This would only affect a simulation if it needed more than 32 bits of randomness in each individual double precision value.)The new method does take significantly longer than before to produce the pseudo-random numbers, but the performance is still competitive with other compilers. The older, faster method may be selected by the -random=5.3 option, and the new method may be confirmed with the -random=7.2 option. These options affect use of
RANDOM_NUMBER
in the file(s) being compiled only; separate files may be compiled with different options and combined in the resulting program. -
The -gline option, which causes a traceback to be produced on error termination,
can now be used with either the -coarray=cosmp option or the -openmp option.
In CoSMP mode, the number of the image (in the initial team) that caused error termination will be
reported, e.g.
ERROR STOP: failatend pco391.f90, line 20: Error occurred in PCO391:SUB pco391.f90, line 18: Called by PCO391:SUB pco391.f90, line 11: Called by PCO391:TEST pco391.f90, line 7: Called by PCO391 Error termination initiated by image 2
and in OpenMP mode, the thread number created by aPARALLEL
construct is reported, e.g.ERROR STOP: failatend suy008.f90, line 19: Error occurred in SUY008:SUB suy008.f90, line 17: Called by SUY008:SUB suy008.f90, line 10: Thread 8 created by OpenMP PARALLEL construct suy008.f90, line 8: Called by SUY008:TEST suy008.f90, line 2: Called by SUY008
- Comments extending past the standard line length are reported separately from statement text that extends past the standard line length.
-
The -xldarg option passes the next argument on the command line to the
linker phase in the position where it occurs, and without any translation (unlike the
-Wl, option, which takes a comma-separated option list).
For example,
nagfor a.o -xldarg -pathlist=abc,xyz b.lib
will typically invoke the linker phase asgcc a.o -pathlist=abc,xyz b.lib NAG-rts-specifications
whereasnagfor a.o -Wl,-pathlist=abc,xyz b.lib
would typically invoke the linker phase asgcc a.o b.lib NAG-rts-specifications -pathlist=abc xyz
-
The -fpplonglines option directs the
fpp
preprocessor not to break output lines that are longer than 132 characters (in free source form). This may be useful if the output offpp
is to be passed to another tool, perhaps thefpp
preprocessor itself, that does not expect#line
directives in the middle of a token that is continued across lines. -
The -w=longlines option suppresses warnings about lines in free source form
that are longer than permitted by the Fortran standard; this is 132 characters up to Fortran 2018,
and 10000 characters for Fortran 2023.
The NAG Fortran Compiler accepts free source form lines of any length.
- The -u=all option specifies that all -u= sub-options are active. In this release, this is -u=external, -u=locality, -u=sharing, and -u=type.
-
The -u=external option specifies that
IMPLICIT NONE (EXTERNAL)
is in effect. This requires that external and dummy procedures must either have an explicit interface, or be explicitly given theEXTERNAL
attribute.For example, if the file
bad.f90
containsProgram bad Call oops End Program
compiling it with the -u=external option will produce the errorError: bad.f90, line 3: External procedure OOPS does not have the EXTERNAL attribute
-
The -u=locality specifies that all
DO CONCURRENT
constructs are treated as if they had specifiedDEFAULT (NONE)
; that locality specifier requires all variables referenced in theDO CONCURRENT
construct to have explicit locality.For example, if the file
b.f90
containsProgram b Real x(100) Do Concurrent(i=1:100) x(i) = i**2.0 End Do Print *,x End Program
compiling it with the -u=locality option will produce the errorError: b.f90, line 4: Locality not specified for X in DO CONCURRENT with DEFAULT(NONE)
-
The -Warn=double_real_literal option reports the presence of default
double precision literal constants in the program.
These are real literal constants with a D exponent letter (and thus, no kind specifier).
The report is as a Note, unless inexactness of the conversion of the decimal to default
double precision is detected, in which case it is a warning.
For example, with the program
Program dlits Print *,123d0 Print *,0.123d0 End Program
the reported warnings are as follows:Note: dlits.f90, line 2: Default double precision literal constant 123D0 Warning: dlits.f90, line 3: Inexact default double precision literal constant 0.123D0
This option may be useful to detect the presence of default double precision literal constants in a program that is intended to have a specified kind type parameter that might not be double precision.
-
The -Warn=unkind_real_literal option reports default real literal constants
in the program that have no kind specifier.
The report is as a Note, unless inexactness of the conversion of the decimal to default real
is detected as being inexact, in which case it is a warning.
For example, with the program
Program lits Print *,123.0 Print *,0.123 End Program
the reported warnings are as follows:Note: lits.f90, line 2: Real literal constant 123.0 has no kind specifier Warning: lits.f90, line 3: Inexact real literal constant 0.123 has no kind specifier
This option may be useful to detect the presence of default (single precision) real literal constants in a program that is intended to be in double precision, or to have a specified kind type parameter that might not be single precision.
-
The -Error=class option specifies treating warning messages in class as errors.
The value of class must be one of the following (not case-sensitive):
Ancient use of an obsolete and non-standard FORTRAN 77 extension; Deleted use of a feature that has been deleted from the Fortran standard; Extension use of a feature that is an extension to the Fortran standard; Obsolescent use of a feature that the Fortran standard says is obsolescent; Questionable valid but questionable usage that may indicate a programming error; Warning any warning-class message other than the above; Any_Warning any of the above. Note that -Error=Obsolescent implies -Error=Deleted, as all deleted features were previously obsolescent. Also, -Error=Extension implies -Error=Ancient, as ancient obsolete extensions are extensions.
Also note that messages do not have their prefix changed, e.g. a warning message will still begin ‘
Warning:
’, but if the -colour option is used, the message colour will be coloured as an error. -
The -strict95 option, which produced obsolescence (warning) messages for the
use of ‘
CHARACTER*
’ syntax, is now enabled by default, and is thus ignored. Instead, there is a new option -nonstrict, which suppresses those messages, and also suppresses extension messages when the declared type of a value for a polymorphic allocatable component is an extension of the declared type of the component (this was always intended to be allowed, but there was a wording error in Fortran 2003 which was not corrected until Fortran 2018). -
Additional -target=machine options are available on Linux and Windows; machine may be nehalem, westmere, sandybridge, ivybridge, haswell, broadwell, skylake, cannonlake, icelake, zen, or native (which targets the current machine).
-
The polish option -elcase=X sets the case to use for exponent letters (
E
orD
): X must be one of Asis, lowercase, UPPERCASE, or an abbreviation thereof; the default is -elcase=UPPERCASE. The interpretation of X is not case-sensitive (e.g. -elcase=u is the same as -elcase=U). Note that -elcase=Asis is only available for basic polishing (=polish), not in Enhanced Polish (=epolish) or any other tool (e.g. =unifyprecision). -
The polish option -canonicalise_floating_literals specifies canonicalisation of floating-point literal constants.
The canonical form of a floating-point literal always has a decimal point, with at least one digit
before it and after it.
If it has an exponent letter of
E
, the exponent is always non-zero. If there is an exponent, the exponent letter is always followed by a sign, and the exponent value has no leading zero. For example,Print *, .1, 1e0, 3d0, 2d-04
would be reformatted (with -elcase=U) as:Print *, 0.1, 1.0, 3.0D+0, 2.0D-4
-
When the -openmp option is used, Polish now auto-terminates OpenMP
DO
constructs, and indents the body thereof. For example, polishing!$OMP do do i=1,10 a(i) = i end do
previously produced!$Omp Do Do i=1,10 a(i) = i End Do
but now produces!$Omp Do Do i=1,10 a(i) = i End Do !$Omp End Do
-
Enhanced polish can add parentheses to argumentless
SUBROUTINE
statements andCALL
statements. By default, the parentheses are omitted (except for aSUBROUTINE
statement with aBIND(C)
clause). The -subroutine_parens option will cause the parentheses to be produced.For example, using enhanced polish with -subroutine_parens (and no other option) on
CALL mysub
will produce the outputCall mysub()
-
When generating Makefile dependencies, the -odir
dir
option specifies that the object files will be located in a different directory (not the current working directory). For example, the object file that depends on “file.f90
” will be considered to be “dir/file.o
” instead of simply “file.o
”.