OPERATOR generic has the VALUE
attribute, it is no longer required to have the INTENT(IN) attribute.
For example,
INTERFACE OPERATOR(+)
MODULE PROCEDURE logplus
END INTERFACE
...
PURE LOGICAL FUNCTION logplus(a,b)
LOGICAL,VALUE :: a,b
logplus = a.OR.b
END FUNCTION
ASSIGNMENT generic has the
VALUE attribute, it is no longer required to have the INTENT(IN) attribute.
For example,
INTERFACE ASSIGNMENT(=)
MODULE PROCEDURE asgnli
END INTERFACE
...
PURE SUBROUTINE asgnli(a,b)
LOGICAL,INTENT(OUT) :: a
INTEGER,VALUE :: b
DO WHILE (IAND(b,NOT(1))/=0)
b = IEOR(IAND(b,1),SHIFTR(b,1))
END DO
a = b/=0 ! Odd number of "1" bits.
END SUBROUTINE
INTEGER FUNCTION factorial(n) RESULT(r)
IF (n>1) THEN
r = n*factorial(n-1)
ELSE
r = 1
END IF
END FUNCTION
is valid, just as if it had been explicitly declared with the RECURSIVE keyword.
This does not apply to assumed-length character functions (where the result is declared with CHARACTER(LEN=*); these remain prohibited from being declared RECURSIVE.
Note that procedures that are RECURSIVE by default are excluded from the effects of the -save option, exactly as if they were explicitly declared RECURSIVE.
RECURSIVE or by default (when the -f2018 or -recursive options are specified).
For example,
ELEMENTAL RECURSIVE INTEGER FUNCTION factorial(n) RESULT(r)
INTEGER,INTENT(IN) :: n
IF (n>1) THEN
r = n*factorial(n-1)
ELSE
r = 1
END IF
END FUNCTION
may be invoked with
PRINT *,factorial( [ 1,2,3,4,5 ] )
to print the first five factorials.
NON_RECURSIVE keyword explicitly declares that a procedure will not be called recursively.
For example,
NON_RECURSIVE INTEGER FUNCTION factorial(n) RESULT(r)
r = 1
DO i=2,n
r = r*i
END DO
END FUNCTION
In Fortran 2008 and older standards, procedures are non-recursive by default, so this keyword has no effect unless the -recursive or -f2018 is being used.