Search code examples
compiler-errorsfortrancompiler-warningsintel-fortran

Why does ifort -warn all throw errors on interface mismatch?


Here is some example code:

! Author: Svetlana Tkachenko svetlana@members.fsf.org
! License: GPLv3 or later

subroutine myprint(var) 
!    integer :: var 
!    print *, 'Hi, my ', var 
end subroutine 

module testing 
   type triangle 
      integer :: point(3) 
   end type 
end module 

program main 
   use testing 
   type(triangle) :: mytriangle 
   mytriangle%point(1)=5 
   call myprint(mytriangle%point(1)) 
end program

it works fine with ifort -c file.f90, but ifort -warn all -c file.f90 results in an error:

blah.f90(4): warning #6717: This name has not been given an explicit type.   [VAR]
subroutine myprint(var) 
-------------------^
blah.f90(4): remark #7712: This variable has not been used.   [VAR]
subroutine myprint(var) 
-------------------^
blah.f90(19): error #6633: The type of the actual argument differs from the type of the dummy argument.   [POINT]
   call myprint(mytriangle%point(1)) 
---------------------------^
compilation aborted for blah.f90 (code 1)

Why does -warn all throw an error? The man page specifically says that all doesn't include errors.

I know I could just fix the code, but I am trying to set up a testing suite for a legacy code base, and I want to be able to run compilation tests with warnings before I start making code changes.


Solution

  • The option -warn all includes the option -warn interfaces inciting interface checking for external procedures where such interfaces can be determined. This is often for interfaces generated from external procedures in separate files compiled with the option -gen-interfaces.

    It is this option -warn interfaces that is responsible for the error message. This is able to check the interface of the external subroutine because that subroutine is in the same file as the program which references it. You have two options, then:

    • have the external subroutine in a distinct file, not compiled with -gen-interfaces;
    • don't use -warn interfaces.

    For this latter, you can use

    ifort -warn all -warn nointerfaces ...
    

    to have all other warnings but the interface checking.

    Preferable to each of those, however, is to have the matching interface. It should be noted, then, that

    subroutine myprint(var) 
    !    integer :: var
    end subroutine 
    

    and

    subroutine myprint(var) 
         integer :: var
    end subroutine 
    

    are two very different things in the presence of default implicit typing rules. They may have the same ultimate effect with having no executable statements (etc.) but the characteristics are quite different.