Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Interfaces of Submodules

FStein93
Beginner
606 Views

I recently stumbled across some Fortran code regarding submodules and compared the Intel HPC kit (version 2021.10.0) and GCC 13.2. For simplicity, I am presenting a modified version of the code given in https://github.com/scivision/fortran-submodule/tree/main/src/overspecified .

 

I was interested in differences between externally defined procedures and procedures defined in submodules.

 

The code as posted below compiles with both compilers, Intel 2021.10.0 and GCC 13.2. If I uncomment the WRITE statement, the Intel compiler still compiles the code whereas GCC 13.2 complains about a mismatch in PURE attribute between the implementation of outer_negate and its interface declaration in the module parent1.

 

Note that both subroutines are declared as pure subroutines in the interface block of the module parent. Beware that outer_negate is implemented outside of the submodule as a PURE function but its implementation lacks the PURE attribute whereas submodule_negate is defined inside of the submodule as a PURE procedure.

 

Is it just not standard compliant code or is it a compiler bug?

 

parent.F90

 

module parent1

implicit none

private

public :: negate

interface
pure subroutine outer_negate(a, b)
integer, intent(in) :: a
integer, intent(out) :: b
end subroutine outer_negate

module pure subroutine submodule_negate(a, b)
integer, intent(in) :: a
integer, intent(out) :: b
end subroutine submodule_negate
end interface

contains

subroutine negate(a, b)
integer, intent(in) :: a
integer, intent(out) :: b

! Dummy to declare separate routines
CALL outer_negate(a, b)
CALL submodule_negate(a, b)
end subroutine negate

end module parent1

 

 

child.F90

 

submodule (parent1) child1

implicit none

contains

module pure subroutine submodule_negate(a, b)
integer, intent(in) :: a
integer, intent(out) :: b
b = -a
end subroutine submodule_negate

end submodule child1

 

subroutine outer_negate(a, b)
integer, intent(in) :: a
integer, intent(out) :: b
b = -a
!write(*,*) a, b
end subroutine outer_negate

 

Thank you for your help.

0 Kudos
1 Reply
FortranFan
Honored Contributor III
549 Views

@FStein93,

Technically the code does not conform, but the onus lies on the author(s) to ensure the explicit interface furnished toward an external procedure is consistent with its implementation.  From what I see in the standard, a processor (compiler being a big part of it) is not required to detect and report the nonconformance even as practitioners will appreciate an eager compiler with a pedantic hat on alerting the user of such an interface mismatch when it is allowed to process both the implementation and the interface.

Nonetheless taking some liberties along such lines (marking an interface as PURE whereas the implementation may not be so relative to the Fortran standard definition of "pure"ity) is something one sees occasionally being done in Fortran codes e.g., with C standard library utilities.

Reply