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
CLASSkeyword, 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
GENERICstatement provides a concise way of declaring generic interfaces. It has the syntax:
where the optional access-spec is eitherGENERIC[ , access-spec ]::generic-spec=>procedure-name-listPUBLICorPRIVATE, 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
GENERICstatement 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
GENERICstatement has the same effect asINTERFACE generic-spec PROCEDURE procedure-name-list END INTERFACEThe 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 Programwill print1.414214 11 -
The
E0exponent width specifier can be used on all edit descriptors that allow the exponent width to be specified (thusE,ENet al, but notD). This specifies formatting with the minimal width for the exponent. For example,Print '(7X,3ES10.2E0)', 1.23, 4.56E24, 7.89D101will print1.23E+0 4.56E+24 7.89E+101 -
The
E,D,ENandESedit descriptors may have a width of zero on output. This provides minimal width editing similarly to theIand 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 forEandD, 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+02E0.4E3.1230E+0021PE0.41.2300E+00EN0.412.3000E+00ES0.41.2300E+01E0.4E0.1230E+2Note 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
EXedit descriptor). -
The
G0.dedit 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 asI0for Integer,L1for Logical, andAfor Character. For example,Print '(7X,"start:",3G0.17,":end")', 123, .True., 'ok'will printstart:123Tok:end -
The new edit descriptors
EXw.dandEXw.dEecan 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 (0Xx0.x1x2… exponent0…9orA…F), and exponent is the binary exponent (power of two) expressed in decimal, with the formatPs z1…zn, where if the optionalEe 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
EXedit descriptor is identical to that of theFedit 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.1might 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-3in this case. -
Input of floating-point numbers with list-directed, namelist, and explicit formatting (e.g. the
Fedit descriptor) accepts input values in hexadecimal-significand form. That is, the form produced by theEXedit 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-3produces the same value as-0XA.P-3. -
The elemental intrinsic function
OUT_OF_RANGEreturns 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
Xis outside the range of values that can be converted to the type and kind ofMOLDwithout error. If theMOLDargument is a variable, it need not have a defined value — only its type and kind are used. TheROUNDargument is only allowed whenXis type Real andMOLDis 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 theROUNDargument 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
Xis an IEEE infinity,OUT_OF_RANGEwill return.TRUE.if and only if the type and kind ofMOLDdoes not support IEEE infinities. Similarly, ifXis an IEEE NaN, the result is true if and only ifMOLDdoes 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
Xis constant and theROUNDargument is missing or constant), only theXargument is permitted to be an array. The result thus always has the rank and shape ofX. -
The
VALUESargument of the intrinsic subroutineDATE_AND_TIMEcan 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
WAITargument of the intrinsic subroutineEXECUTE_COMMAND_LINEcan be any kind of logical. TheCMDSTATandEXITSTATarguments 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 Programwill, assuming ‘echo’ is the Unix echo command, displayok -
The intrinsic subroutines
GET_COMMAND,GET_COMMAND_ARGUMENTandGET_ENVIRONMENT_VARIABLEnow have an optionalERRMSGargument at the end of the argument list. If an error occurs (i.e., a positive value would be assigned to theSTATUSargument), theERRMSGargument will be assigned an explanatory message. If no error occurs (zero or a negative value would be assigned to theSTATUSargument), theERRMSGargument remains unchanged. Note that the effect on theERRMSGargument occurs (or does not occur) even if theSTATUSargument is omitted. But as it is unchanged when no error occurs, it is not a substitute for theSTATUSargument 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 Programwill, unless there is an environment variable called ‘Does Not Exist’, print something likeEnvironment variable does not exist -
The intrinsic function
IMAGE_INDEXhas two additional forms:IMAGE_INDEX( COARRAY, SUB, TEAM ) IMAGE_INDEX( COARRAY, SUB, TEAM_NUMBER )
The meanings of theTEAM: scalar of typeTEAM_TYPE,Intent(In);
TEAM_NUMBER: scalar of type Integer,Intent(In).COARRAYandSUBarguments 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_INITinitialises 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_DISTINCTis 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. IfREPEATABLEis true, each execution of the program will use the same initial seed (image-dependent ifIMAGE_DISTINCTis 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_INITis 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_AWAYis 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_FMAperforms 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)+Cwith only one rounding; that is, the whole operation is computed mathematically and only rounded to the format ofAat the end. For example,IEEE_OVERFLOWis not signalled ifA×Boverflows, but only if the final result is out of range.Restriction: this function must not be invoked when the kind of
Ais not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (A)returns false. -
The pure subroutine
IEEE_GET_MODESretrieves the halting modes, rounding modes, and underflow mode in a single object. Its syntax is:IEEE_GET_MODES (MODES)
The retrieved modes can be used byMODES: scalar of typeIEEE_MODES_TYPE,Intent(Out).IEEE_SET_MODESto 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_VALUEargument is assigned the current rounding mode for the specified radix. IfRADIXdoes not appear, the binary rounding mode is assigned. -
The elemental function
IEEE_INTconverts 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 kindKINDifKINDappears, otherwise default kind.The value of
Ais 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_INVALIDis signalled.This operation is either the
convertToInteger{round}or theconvertToIntegerExact{round}operation specified by the IEEE standard. If it is the latter, andIEEE_INVALIDwas not signalled, butAwas not already an integer,IEEE_INEXACTis signalled.Restriction: this function must not be invoked when the kind of
Ais 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_MAGperform maximum/minimum operations ignoring NaN values. If an argument is a signalling NaN,IEEE_INVALIDis 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_NUMis:IEEE_MAX_NUM (X, Y)
The value of the result is the maximum value ofX: type Real;
Y: same type and kind asX;
Result : same type and kind asX.XandY, ignoring NaN.Restriction: this function must not be invoked when the kind of
Xis not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (X)returns false.The
IEEE_MAX_NUM_MAGhas the same syntax (apart from the name), and the result is whichever ofXandYhas the greater magnitude. The same restriction applies.The
IEEE_MIN_NUMhas the same syntax (apart from the name), and the result is the minimum value ofXandY, ignoring NaN. The same restriction applies.The
IEEE_MIN_NUM_MAGhas the same syntax (apart from the name), and the result is whichever ofXandYhas the smaller magnitude. The same restriction applies. -
The derived type
IEEE_MODES_TYPEcontains the all the floating-point modes: the halting modes, the rounding modes, and the underflow mode. It is used by theIEEE_GET_MODESandIEEE_SET_MODESsubroutines. -
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_INVALIDexception is raised.IEEE_QUIET_EQandIEEE_QUIET_NEare exactly the same as==and/=, apart from only being usable on IEEE format numbers. TheIEEE_QUIET_EQfunction 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_NEet 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_REALconverts an Integer or IEEE format Real value to the specified IEEE format Real value. Its syntax is:IEEE_REAL (A, [, KIND ])
If the value ofA: type Real or Integer;
KIND(optional) : scalar Integer constant expression;
Result : type Real, with kindKINDifKINDappears, otherwise default kind.Ais representable in the kind of the result, that value is the result. Otherwise, the value ofAis rounded to the kind of the result using the current rounding mode.Restriction: this function must not be invoked when the kind of
Aor 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_MODESsets the halting modes, rounding modes, and underflow mode to the state when a previous call toIEEE_GET_MODESwas made. Its syntax is:IEEE_SET_MODES (MODES)
The value ofMODES: scalar of typeIEEE_MODES_TYPE,Intent(In).MODESmust 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. IfRADIXdoes not appear, the binary rounding mode is set.Restriction: This subroutine must not be invoked unless there is some
X(with radixRADIXif 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_INVALIDexception if an operand is a NaN (whether quiet or signalling).IEEE_SIGNALING_LT,IEEE_SIGNALING_LE,IEEE_SIGNALING_GTandIEEE_SIGNALING_GEare exactly the same as<,<=,>and>=, apart from only being usable on IEEE format numbers. TheIEEE_SIGNALING_EQfunction 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_NEet 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_SIGNBITqueries 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
Xis not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (X)returns false. -
The elemental function
IEEE_RINTnow 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
ROUNDis present, the result is the value ofXrounded to an integer according to the mode specified byROUND; this is the operation the IEEE standard callsroundToIntegral{rounding}. WhenROUNDis absent, the result is the value ofXrounded 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
Xis not an IEEE format, i.e. ifIEEE_SUPPORT_DATATYPE (X)returns false.
-
The named constant
-
The named constant
C_PTRDIFF_Thas 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 Interfaceinteroperates with the C functionptrdiff_t diff_cptr(void *a,void *b) { return a - b; } -
In the intrinsic module
ISO_C_BINDING, the proceduresC_LOCandC_FUNLOCare considered to be pure procedures, andC_F_POINTERandC_F_PROCPOINTERare considered to be impure. When it is used within a pure procedure, the argument ofC_FUNLOCmust also be a pure procedure. -
The default accessibility in a module of entities accessed from another module (via the
USEstatement) can be controlled by specifying that module name in aPUBLICorPRIVATEstatement, 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 Moduleall the entities inISO_FORTRAN_ENVare by defaultPRIVATEin modulemymod, without needing to list them individually.This new default accessibility can be overridden by an explicit
PUBLICorPRIVATEdeclaration. Also, if an entity in a remote module (two or moreUSEstatements away) is accessed by more than one intervening module, it is defaultPRIVATEonly if every route to the entity is defaultPRIVATE, and defaultPUBLICif 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 Modulethe variables
AandBin moduleREMOTEarePUBLICin moduleMY_MODULE, because they are accessible via moduleROUTE_TWOwhich is defaultPUBLIC. -
The
IMPLICIT NONEstatement can now haveTYPEandEXTERNALspecifiers. Its full syntax is now:
where implicit-none-specifier-list is a comma-separated list of the keywordsIMPLICIT NONE[([ implicit-none-specifier-list ])]EXTERNALandTYPE. No keyword may appear more than once in the list. If the list does not appear, or ifTYPEappears in the list, no otherIMPLICITstatement may appear in the scoping unit.The semantics of:
andIMPLICIT NONE ()
are identical to that ofIMPLICIT NONE (TYPE)IMPLICIT NONEIf the keyword
EXTERNALappears, a procedure with an implicit interface that is referenced in the scoping unit must be given theEXTERNALattribute explicitly: that is, it must be declared in anEXTERNALstatement, in a type declaration statement that has theEXTERNALattribute, or in a procedure declaration statement. For example,Subroutine sub(x) Implicit None (External) Integer f Print *,f(x) End Subroutinewill produce an error for the reference to the functionF, because it does not have theEXTERNALattribute.If the keyword
EXTERNALappears and the keywordTYPEdoes not appear, implicit typing is not disabled, and otherIMPLICITstatements may appear in the scoping unit. If both the keywordsTYPEandEXTERNALappear, both implicit typing is disabled, and theEXTERNALattribute is required for implicit-interface procedures. -
The
IMPORTstatement can appear inBLOCKconstructs 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,ONLYstatements. Like otherIMPORTstatements, they can appear only in interface bodies,BLOCKconstructs, and contained subprograms, and appear in betweenUSEstatements and other specification statements.The
IMPORT,NONEstatement 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,NONEstatement appears in a scoping unit, no otherIMPORTstatement 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 SubroutinetheXin subroutineINNERis not a reference to theXin its hostOUTER, but is an implicitly typed (Integer) variable that is local toINNER.The
IMPORT,ALLstatement 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 ofYinsideINNERis invalid, and will produce a compilation error. If anIMPORT,ALLstatement appears in a scoping unit, no otherIMPORTstatement may appear.The
IMPORT,ONLYstatement specifies that only host entities named inIMPORT,ONLYstatements are accessible by host association. If anIMPORT,ONLYstatement appears in a scoping unit, all otherIMPORTstatements must have theONLYkeyword. For example, inSubroutine outer(x,y,z) Real,Intent(InOut) :: x, y(:),z … Contains Subroutine inner Import,Only:x,y z = x + ythe references toXandYinINNERare references to the host (OUTER) entities, but the reference toZinINNERis to an implicitly-typed local variable. -
An implied
DOloop in an array constructor, or in aDATAstatement, may now have an Integer type-spec preceding the loop control. The syntax for such a loop in the array constructor is
and for such a loop in a(ac-value-list,integer-type-spec::ac-do-variable=from,to [,step ])DATAstatement is
where the integer-type-spec is any type-spec beginning with the keyword(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-
DOvariable (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 ofYto 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 functionFto each element ofA, even if the bounds are, for example 20000000000:20000000005. -
The
DO CONCURRENTconstruct 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 CONCURRENTto be given an explicit locality. The revised syntax of theDO CONCURRENTstatement, ignoring labels and construct names, is:
where concurrent-header is the same as before, and each locality-spec is one of:DO CONCURRENTconcurrent-header [ locality-spec ]...
A variable that appears in aLOCAL (variable-name-list)
LOCAL_INIT (variable-name-list)
SHARED (variable-name-list)
DEFAULT (NONE)LOCALorLOCAL_INITspecifier must be a rather ordinary variable: it must not have theALLOCATABLEorOPTIONALattribute, 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 thePOINTERattribute. Finally, it must be permitted to appear in a variable definition context: for example, it cannot beINTENT(IN). The effect ofLOCALandLOCAL_INITis 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 thatLOCALandLOCAL_INITvariables cannot cause any dependency between iterations.A variable that is
SHAREDis 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 theCONTIGUOUSattribute).Providing locality specifiers for variables in a
DO CONCURRENTconstruct 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
IFstatement 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.f90containsSubroutine sub(x) Real,Intent(In) :: x If (x) 1,2,3 1 Stop 1 2 Stop 2 3 Stop 3 End Subroutinethis warning message will be produced:Deleted feature used: del.f90, line 3: Arithmetic IF statementIf the -Error=Deleted option is used, this will be treated as an error. -
The
DOconstruct with a label is considered to be Obsolescent (it is effectively replaced by theEND DOstatement and construct labels). Furthermore, the non-blockDOconstruct is treated as a Deleted feature. A non-blockDOis either two or more nestedDOloops with a sharedDOtermination label, or aDOloop with a terminating statement other thanEND DOorCONTINUE. (This is because these are hard to understand, error-prone, and better functionality has been available via the blockDOconstruct since Fortran 90.) For example, if the fileobsdel.f90containsSubroutine 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 Subroutinethese 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
FORALLstatement and construct are considered to be Obsolescent. This is because it usually has worse performance than ordinaryDOorDO CONCURRENT. For example, if the fileobs.f90containsSubroutine 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 Subroutinethis 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_KINDorOMP_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_KINDreturns 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
BITSbits; ifBITSis greater than the storage size of the largest kind of Logical, the result is −1. Thus any value ofBITSless 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 ifBITSis greater than 64, as its largest supported Logical kind has 64 bits. -
The standard intrinsic module
ISO_FORTRAN_ENVcontains additional named constants, supplying the kind type parameter values for Logical kinds with the indicated bit sizes:LOGICAL8,LOGICAL16,LOGICAL32andLOGICAL64. If there is no kind of Logical whose storage size is exactly the size indicated, the constant has the value −1. -
The
ATedit 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)', awill display the lineokaywith no trailing blanks.The
ATedit descriptor is not allowed for input (READstatements).
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
FORMATstatement 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 Programwill produce the warning messageWarning: na.f90, line 4: In E9.3 the width 9 may be too small for output of some numbersIf 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.3in 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 asterisksand 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 Programproduces 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 Subroutineproduces 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 TEAMconstruct 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 Subroutineproduces 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_NUMBERnow 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_NUMBERin 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 2and in OpenMP mode, the thread number created by aPARALLELconstruct 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.libwill typically invoke the linker phase asgcc a.o -pathlist=abc,xyz b.lib NAG-rts-specificationswhereasnagfor a.o -Wl,-pathlist=abc,xyz b.libwould typically invoke the linker phase asgcc a.o b.lib NAG-rts-specifications -pathlist=abc xyz -
The -fpplonglines option directs the
fpppreprocessor not to break output lines that are longer than 132 characters (in free source form). This may be useful if the output offppis to be passed to another tool, perhaps thefpppreprocessor itself, that does not expect#linedirectives 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 theEXTERNALattribute.For example, if the file
bad.f90containsProgram bad Call oops End Programcompiling 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 CONCURRENTconstructs are treated as if they had specifiedDEFAULT (NONE); that locality specifier requires all variables referenced in theDO CONCURRENTconstruct to have explicit locality.For example, if the file
b.f90containsProgram b Real x(100) Do Concurrent(i=1:100) x(i) = i**2.0 End Do Print *,x End Programcompiling 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 Programthe 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.123D0This 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 Programthe 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 specifierThis 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 (
EorD): 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-04would 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
DOconstructs, and indents the body thereof. For example, polishing!$OMP do do i=1,10 a(i) = i end dopreviously produced!$Omp Do Do i=1,10 a(i) = i End Dobut now produces!$Omp Do Do i=1,10 a(i) = i End Do !$Omp End Do -
Enhanced polish can add parentheses to argumentless
SUBROUTINEstatements andCALLstatements. By default, the parentheses are omitted (except for aSUBROUTINEstatement 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 mysubwill produce the outputCall mysub() -
When generating Makefile dependencies, the -odir
diroption 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”.