The code below discussed in an interp is accepted by ifort (as it is by nagfor and gfortran, but rejected by PGI fortran). According to J3, the code
is invalid: https://j3-fortran.org/doc/year/11/11-219r1.txt
I am not sure whether the compiler actually has to catch this as the standard uses 'shall', but I opened a support request to clarify with the intel team. Here is the code:
MODULE M1 INTERFACE SUBR MODULE PROCEDURE SUBR1 END INTERFACE CONTAINS SUBROUTINE SUBR1 END SUBROUTINE END MODULE M2 INTERFACE SUBR MODULE PROCEDURE SUBR2 END INTERFACE CONTAINS SUBROUTINE SUBR2 END SUBROUTINE END PROGRAM MAIN USE M1 CALL S CONTAINS SUBROUTINE S USE M2 CALL SUBR END SUBROUTINE END
I must preface this by I am not as versed in the standards as others here. However, what is the difference between above and:
PROGRAM MAIN integer :: I ... CALL S CONTAINS SUBROUTINE S integer :: I ! different I ... END SUBROUTINE END
The variable I, declared (and used) in the scope of the contained subroutine does not conflict with I of the outer procedure, rather it replaces it. So why wouldn't this (scope replacement) also apply to generic interfaces? IOW as long as the named entity is locally known (i.e. does not have the same named external name), I would assume this is permitted.
Can the generic name be the same in both modules, but the arguments (and procedure name) differ. IOW can the generic name be essentially extended with the new/additional types?
Yes, absolutely. The constraint in question is this:
C1215 Within the scope of a generic name, each pair of procedures identified by that name shall both be subroutines or both be functions, and
(3) at least one of them shall have both
(a) a nonoptional non-passed-object dummy argument at an effective position such that either the other procedure has no dummy argument at that effective position or the dummy argument at that position is distinguishable from it, and
(b) a nonoptional non-passed-object dummy argument whose name is such that either the other procedure has no dummy argument with that name or the dummy argument with that name is distinguishable from it.
and the dummy argument that disambiguates by position shall either be the same as or occur earlier in the argument list than the one that disambiguates by name.
In the case here, both definitions of SUBR lack any disambiguating, nonoptional dummy arguments.
.. The variable I, declared (and used) in the scope of the contained subroutine does not conflict with I of the outer procedure, rather it replaces it. So why wouldn't this (scope replacement) also apply to generic interfaces? IOW as long as the named entity is locally known (i.e. does not have the same named external name), I would assume this is permitted.
You may want to refer to scoping units and local identifiers in the Fortran standard, say 2008 revision given that's what the "answer" on the J3 interp request refers to even though the number F03/116 implies the previous version: https://wg5-fortran.org/f2008.html
My own simple-minded understanding is since the standard treats
- a "program unit" (the instructions in PROGRAM MAIN in the original post) as a "scoping unit";
- and module procedures, generic interfaces, and other entities accessed via USE are "local identifiers";
- and the standard specifies these local identifiers to be of "inclusive scope" (as in, say, the scope extending into the contained subprogram);
- and "Within its scope, a local identifier of one class shall not be the same as another local identifier of the same class",
- "except that a generic name may be the same as the name of a procedure as explained in 22.214.171.124", indicating rules for per section 12.4 for generic name resolutions and ability to distinguish names, etc.
the code in the original post becomes non-conforming since SUBR1 and SUBR2 are ultimately indistinguishable under the generic name SUBR and the compiler is REQUIRED to diagnose it per constraint C1215 as indicated by Steve.
Whereas the code you show with a named variable "INTEGER :: I" is not in the class of :"local identifier" with above-mentioned restrictions, so it is permitted.
As Steve said, the compiler is required to be able to diagnose specific violations of the standard. This permits the choice frequently made in ifort to require options such as -stand to enable the diagnosis. You might still file a ticket, since there seems to be no reason why this diagnosis should be capable of being turned off. The usual reason for disabling diagnosis is for usage commonly handled in an expected way by other compilers or previous standards, even extinct ones, going back to PDP.