`optional` character argument to call a procedure interface: unexpected

@FedericoPerini ,

Your question here builds off of the earlier one you asked recently. Just as in that other thread, the onus lies on the program author to conform, a processor is not required to detect and report the issue. The program response falls under the processor-dependent category which can include a nasty run-time exception or worse.

For the sake of other readers who may not be as familiar with Fortran when it comes to generic resolution with the so-called overloaded methods, OPTIONAL attribute, etc., here is a somewhat stripped down scenario of what you post:

module m
   generic :: sub => sub1, sub2
contains
   subroutine sub1( n )
      integer, intent(in) :: n
      print *, "sub1: n = ", n
   end subroutine 
   subroutine sub2( n, s )
      integer, intent(in) :: n
      character(len=*), intent(in) :: s
      print *, "sub2: n = ", n, "; s = ", s 
   end subroutine 
end module
module n
   use m, only : sub
contains
   subroutine subn( n, s )
      integer, intent(in) :: n
      character(len=*), intent(in), optional :: s
      call sub( n, s )  !<-- this will resolve to sub2
   end subroutine 
end module
   use n
   call subn( 42 )
end 

and as commented on line 20, the generic resolution rules in the standard will point the compiler to resolve to sub2 when you may seek sub1.

C:\temp>ifort /standard-semantics /free p.f
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.10.0 Build 20230609_000000
Copyright (C) 1985-2023 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.36.32537.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\temp>p.exe
 sub2: n =  42 ; s =

The easiest workaround is as presented by @vmagnin upthread:

   ..
   subroutine subn( n, s )
      integer, intent(in) :: n
      character(len=*), intent(in), optional :: s
      if ( present(s) ) then
         call sub( n, s )
      else
         call sub( n )
      end if
   end subroutine
   .. 
3 Likes