If you remove the module ifort/ifx runs the following example it gets the same results as if you use the module with ifort and gfortran. The overload (which is standard-conforming) and the Intel extension produce the same result for the default LOGICAL kind. It would take a rather long general procedure to support all the logical kinds so they could be combined in expressions and passed as arguments and get the expected kind put it is possible; but the extension already handles that. Since == and .EQ. are bound as the same operator (if you define overload â==â you also overload â.EQ.â) and at least the ifort/ifx and nvfortran compilers already support this as an extension I am confused by those statements.
module logical_ops
!use,intrinsic :: iso_fortran_env, only : logical8, logical16, logical32, logical64
use,intrinsic :: iso_fortran_env, only : int8, int16, int32, int64
implicit none
integer,parameter :: logical8=1, logical16=2, logical32=4,logical64=8 ! compiler-dependent kludge
interface operator(==); module procedure equal; end interface
interface operator(/=); module procedure notequal; end interface
contains
logical function equal(l1, l2); logical, intent(in) :: l1, l2; equal = l1 .eqv. l2; end
logical function notequal(l1, l2); logical, intent(in) :: l1, l2; notequal = l1 .neqv. l2; end
end module
program testit
use logical_ops
implicit none
logical :: l=.false.,m=.false.,n=.false.
print *,'L.AND.M.EQ.N', l.and.m.eq.n
print *,'L.AND.(M.EQ.N)',l.and.(m.eq.n)
print *,'(L.AND.M).EQ.N',(l.and.m).eq.n
print *
print *,'L.AND.M.EQV.N',l.and.m.eqv.n
print *,'L.AND.(M.EQV.N)',l.and.(m.eqv.n)
print *,'(L.AND.M).EQV.N',(l.and.m).eqv.n
print *
print *,'L.AND.M == N',l.and.m==n
print *,'L.AND.(M == N)',l.and.(m==n)
print *,'(L.AND.M) == N',(l.and.m)==n
end program testit
So âifort testit.f90â and ânvfortran testit.f90â and âifx testit.f90â work with an extension without the module,
and an overload produces the same results with âgfortran testit.f90â and âifx -stand=f90â as the extension I do not see that it would break anything to standardize the behavior to the same extend as a more general overload module would with at least those compilers. The problem would be with a further extension that included being able to interchange LOGICAL and INTEGER values.
The fact it is such a common extension and has been for a very long time, and that it is rather intuitive is the reason it appears in so much legacy code. If you try something like " (a.eq.1).and.(b<0)" and it works you are unlikely to think that is non-standard until a compiler warning or error tells you otherwise. Expressions mixing integer and logical are another matter, as that would break some old codes to define TRUE as a particular bit pattern and/or require a rule for converting arbitrary INTEGER values to a LOGICAL value.