Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor I
11 Views

Ifort accepts invalid code

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

 

0 Kudos
8 Replies
Highlighted
11 Views

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.

Jim Dempsey

0 Kudos
Highlighted
11 Views

There is likely a conflict if your code has

PROGRAM FOO
    USE M1
    USE M2
    ....

Now the two generic interfaces are residing in the same scope.

Jim Dempsey

0 Kudos
Highlighted
Black Belt Retired Employee
11 Views

This is a constraint (C1215) so a compiler is required to be able to diagnose it. Inside S, both interfaces are in scope of the generic name.

0 Kudos
Highlighted
11 Views

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?

Jim Dempsey

0 Kudos
Highlighted
Black Belt Retired Employee
11 Views

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.

0 Kudos
Highlighted
Valued Contributor III
11 Views

jimdempseyatthecove wrote:

.. 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.

Jim Dempsey

 

Jim,

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 12.4.3.4", 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.

0 Kudos
Highlighted
Black Belt
11 Views

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.

0 Kudos
Highlighted
Valued Contributor I
11 Views

Tim, I filed a ticket with Intel Support, 04052958.

0 Kudos