xxx_genmod.f90 files and interface checking

xxx_genmod.f90 files and interface checking

How close to the "actual" interface of an external procedure is it expected that the source in the /warn:interfaces generated Xxxx__genmod.f90 files should be?  Should I expect the _genmod.f90 files to be "correct" compilable source?  Would missing USE statements and "extra" USE statements not present in the specification part of the original external procedure be indicative of trouble elsewhere, and worth chopping out an example?

11 post / 0 nuovi
Ultimo contenuto
Per informazioni complete sulle ottimizzazioni del compilatore, consultare l'Avviso sull'ottimizzazione

Hi Jan,

I don't know whether it helps, but I don't have any "use" statements in my automatically compiler generated interfaces although the original routines have "use module xy". (I assume you meant subroutines as external procedures).

Modules should not be necessary to judge the correctness of an interface, at least in simple procedure oriented programming. Or am I wrong?

Best regards,

Johannes

Ritratto di Lorri Menard (Intel)

I talked to our gen_interfaces guy, and yes, if you have a simple example that would be helpful.

    thanks -

                           --Lorri

This one is being a little slippery.  But consider:

MODULE ParseNodes
  IMPLICIT NONE
  PRIVATE
  
  TYPE, PUBLIC, ABSTRACT :: ParseNode
  CONTAINS                                            ! #A
    PROCEDURE(pnode_Dump), DEFERRED :: Dump           ! #A
  END TYPE ParseNode
  
  TYPE, PUBLIC :: ParseNodeElement
    CLASS(ParseNode), ALLOCATABLE :: item
  END TYPE ParseNodeElement
  
  ABSTRACT INTERFACE
    SUBROUTINE pnode_Dump(pnode, unit, pfx)
      IMPORT :: ParseNode
      IMPLICIT NONE
      !-------------------------------------------------------------------------
      CLASS(ParseNode), INTENT(IN) :: pnode
      INTEGER, INTENT(IN) :: unit
      CHARACTER(*), INTENT(IN) :: pfx
    END SUBROUTINE pnode_Dump
  END INTERFACE
END MODULE ParseNodes
MODULE StNodes
  IMPLICIT NONE
  PRIVATE
  !-----------------------------------------------------------------------------
  TYPE, ABSTRACT, PUBLIC :: StNode
    CLASS(StNode), POINTER :: parent => NULL()
  END TYPE StNode
  
  TYPE, PUBLIC :: StNodeElement
    CLASS(StNode), ALLOCATABLE :: item
  END TYPE StNodeElement
END MODULE StNodes
MODULE IfStmts
  USE ParseNodes
  IMPLICIT NONE
  PRIVATE
END MODULE IfStmts
SUBROUTINE ParseExecutionPartConstructListExternal(stmts, children)
  USE ParseNodes
  USE StNodes
  USE IfStmts
  IMPLICIT NONE
  !-----------------------------------------------------------------------------
  TYPE(StNodeElement), INTENT(IN) :: stmts(:)
  TYPE(ParseNodeElement), INTENT(OUT), ALLOCATABLE :: children(:)
END SUBROUTINE ParseExecutionPartConstructListExternal

>ifort /c /check:all /warn:all /standard-semantics BodgyGenmodThings.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.0.103 Build 201307
28
Copyright (C) 1985-2013 Intel Corporation.  All rights reserved.
BodgyGenmodThings.f90(45): remark #7712: This variable has not been used.   [STMTS]
SUBROUTINE ParseExecutionPartConstructListExternal(stmts, children)
---------------------------------------------------^
BodgyGenmodThings.f90(45): remark #7712: This variable has not been used.   [CHILDREN]
SUBROUTINE ParseExecutionPartConstructListExternal(stmts, children)
----------------------------------------------------------^
[U:projectsifort 14.0 testbodgy-genmod]
>type parseexecutionpartconstructlistexternal__genmod.f90
        !COMPILER-GENERATED INTERFACE MODULE: Wed Oct 09 22:24:34 2013
        MODULE PARSEEXECUTIONPARTCONSTRUCTLISTEXTERNAL__genmod
          INTERFACE
            SUBROUTINE PARSEEXECUTIONPARTCONSTRUCTLISTEXTERNAL(STMTS,   &
     &CHILDREN)
              USE IFSTMTS
              USE STNODES
              TYPE (STNODEELEMENT), INTENT(IN) :: STMTS(:)
              TYPE (PARSENODEELEMENT) ,ALLOCATABLE, INTENT(OUT) ::      &
     &CHILDREN(:)
            END SUBROUTINE PARSEEXECUTIONPARTCONSTRUCTLISTEXTERNAL
          END INTERFACE
        END MODULE PARSEEXECUTIONPARTCONSTRUCTLISTEXTERNAL__genmod

Note how the ParseNodes module does not appear in the use statements in the generated interface source snippet, yet that module is the only thing that can provide the ParseNodeElement type required for the dummy argument.

Comment out the type bound procedure part of the ParseNode type (the lines marked #A) and the IfStmt module in the generated interface body changes to ParseNodes.

I have strong suspicions that in larger, more complicated examples (hundreds of source files) this, or something like it, leads to the compiler babbling incoherent nonsense about required interfaces missing for external procedures (even though the interfaces are declared just a few lines previous), and possibly an ICE.

Ritratto di Lorri Menard (Intel)

Excellent, thanks ... I'll share your example.

Ritratto di Steve Lionel (Intel)

Here's a summary of how generated interfaces are supposed to work:

  • When a procedure is compiled that is not in a module or contained, a generated interface module is constructed. Two files are created - one, the .mod, is used later by the compiler (see below). A .f90 is also created - this is supposed to reflect the generated interface, and most cases does exactly, but sometimes there are attributes that don't make it in if they're not required for error checking. The compiler never looks at the .f90 - it's simply there for your viewing pleasure.
  • When the compiler sees a reference to a procedure for which there is no explicit interface, it checks to see if a generated interface module exists. If it does, it uses the generated interface for error checking ONLY - making sure number of arguments, types match, etc. If it notices that the actual routine has aspects that the language requires an explicit interface for, such as OPTIONAL or deferred-shape dummy arguments, it will complain. The compiler will also compare any INTERFACE block you have against generated interfaces to make sure they match.
  • Note again that generated interfaces are only for error checking - they do NOT replace explicit interfaces where the language requires them.
  • Order of compilation is important - if the call is compiled before the caller, there's no interface to check. (If the call and caller are in the same source file, though, it does check even if the call is first.)

Now, over the years we have had some bugs in the area. Sometimes the compiler inappropriately used the information in the generated interface to supply details where the language requires an interface. And sometimes just enabling this feature triggers other errors due to the extra pass through the code it makes. That said, it's pretty solid nowadays, though nothing is perfect, so examples of problems are always welcome.

Steve
Ritratto di app4619

is there any option to supress the ouput of the f90 interface checking is very useful but I never look at the f90 files and there are severals hundered files created.

Ritratto di Steve Lionel (Intel)

There is not such an option, but these are created in the module output folder and you could delete them all with a simple rule if needed. There would also be the same number of .mod files. One way to reduce these is to not rely on implicit interfaces!

Steve
Ritratto di Lorri Menard (Intel)

There is a switch that will remove the .f90 files after the .mod files have been created:
    /gen-interfaces:nosource

 

 

 

Ritratto di app4619

 /gen-interfaces:nosource does indeed do the trick, thanks Lorri. 

Well.. I need new glasses, or fingers.  The genmod.f90 oddity above aside, the reason I was seeing "Fool!  You need an interface!!" kind of erors is becase I cannott spel when typping the procdure name in the intrface blck.  I'll fish an example for the ICE out another day, my head is too sore at the moment from banging it on my desk in penance.

Accedere per lasciare un commento.