Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

UDDTIO: some conflict with /iface:mixed_str_len_arg compiler option and v_list edit descriptor?

FortranFan
Honored Contributor II
502 Views

We're running into difficulties while trying to use the UDDTIO feature and the problem seems to have connection with /iface:mixed_str_len_arg compiler option that has to be applied in the project for compatibility with other libraries used in another section of code.  After a lot of misdirection at trying to figure out the root cause and some scorched path along the way, here's what appears to be a reproducer of the problem.

Consider the following simple code from Fortran 2008 standard, WD 1539-1 J3/10-007r1 (F2008 Working Document) 24th November 2010 16:43, Note 9.48:

module p

   implicit none

   type :: person
      character (len=20) :: name
      integer :: age
   contains
      procedure,private :: pwf
      generic :: write(formatted) => pwf
   end type person

contains

   subroutine pwf (dtv,unit,iotype,vlist,iostat,iomsg)
   
      ! argument definitions
      class(person), intent(in) :: dtv
      integer, intent(in) :: unit
      character (len=*), intent(in) :: iotype
      integer, intent(in) :: vlist(:)
      integer, intent(out) :: iostat
      character (len=*), intent(inout) :: iomsg
      
      ! local variable
      character (len=9) :: pfmt
      
      ! vlist(1) and (2) are to be used as the field widths of the two
      ! components of the derived type variable. First set up the format to
      ! be used for output.
      write(pfmt,'(A,I2,A,I2,A)', iostat=iostat, iomsg=iomsg ) '(A', vlist(1), ',I', vlist(2), ')'
      if (iostat /= 0) return
      
      ! now the basic output statement
      write(unit, fmt=pfmt, iostat=iostat, iomsg=iomsg) dtv%name, dtv%age
      if (iostat /= 0) return
      
      return
      
   end subroutine pwf

end module p
program committee

   use p

   integer :: id
   integer :: members
   type (person) :: chairman

   id = 1
   chairman%name = "John Doe"
   chairman%age = 50
   members = 5

   write(6, fmt="(I2, DT(15,6), I5)" ) id, chairman, members
   ! this writes a record with four fields, with lengths 2, 15, 6, 5
   ! respectively

   stop

end program

Here's the compiler and execution response:

C:\..>ifort -c /standard-semantics /stand /warn:all /iface:mixed_str_len_arg m.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R
) 64, Version 17.0.0.109 Build 20160721
Copyright (C) 1985-2016 Intel Corporation.  All rights reserved.

m.f90(15): remark #7712: This variable has not been used.   [IOTYPE]
   subroutine pwf (dtv,unit,iotype,vlist,iostat,iomsg)
----------------------------^

C:\..>ifort -c /standard-semantics /stand /warn:all /iface:mixed_str_len_arg p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R
) 64, Version 17.0.0.109 Build 20160721
Copyright (C) 1985-2016 Intel Corporation.  All rights reserved.


C:\..>link /out:p.exe /subsystem:console p.obj m.obj
Microsoft (R) Incremental Linker Version 12.00.40629.0
Copyright (C) Microsoft Corporation.  All rights reserved.


C:\..>p.exe
forrtl: severe (157): Program Exception - access violation
Image              PC                Routine            Line        Source

p.exe              000000013F1112ED  Unknown               Unknown  Unknown
p.exe              000000013F117A41  Unknown               Unknown  Unknown
p.exe              000000013F1111A7  Unknown               Unknown  Unknown
p.exe              000000013F16B25E  Unknown               Unknown  Unknown
p.exe              000000013F16B534  Unknown               Unknown  Unknown
kernel32.dll       00000000778759CD  Unknown               Unknown  Unknown
ntdll.dll          0000000077AAA2E1  Unknown               Unknown  Unknown

C:\..>

Looking in the debugger, it would appear some adverse impact on v_list edit descriptor (vlist dummy argument in the pwf defined IO procedure above) with the /iface:mixed_str_len_arg option.  The code should compile and execute just fine without this option. 

0 Kudos
4 Replies
Steven_L_Intel1
Employee
502 Views

Any sort of "callback" procedure must have default calling conventions. We'll see if we can do a better job of alerting you to this, though there are some times we can't tell.

0 Kudos
FortranFan
Honored Contributor II
502 Views

Steve Lionel (Intel) wrote:

Any sort of "callback" procedure must have default calling conventions. We'll see if we can do a better job of alerting you to this, though there are some times we can't tell.

Excellent, Steve.  Just as a quick check, the following 'quick and dirty' workaround with compiler directive '!dir$ attributes' helps with the situation in the original post.  We'll change the project to now employ all default calling conventions and where we 'use' the external libraries with some of the non-default stuff may be necessary, we'll apply '!dir$ attributes mixed_str_len_arg .. ' in those interfaces to get the code working correctly.

module m

   implicit none

   type :: person
      character (len=20) :: name
      integer :: age
   contains
      !private
      procedure, private :: pwf
      generic :: write(formatted) => pwf
   end type person

contains

   subroutine pwf (dtv,unit,iotype,vlist,iostat,iomsg)
      !dir$ attributes default :: pwf

      ! argument definitions
      class(person), intent(in)        :: dtv
      integer, intent(in)              :: unit
      character (len=*), intent(in)    :: iotype
      integer, intent(in)              :: vlist(:)
      integer, intent(out)             :: iostat
      character (len=*), intent(inout) :: iomsg

      ! local variable
      character (len=9) :: pfmt

      ! vlist(1) and (2) are to be used as the field widths of the two
      ! components of the derived type variable. First set up the format to
      ! be used for output.
      write(pfmt,'(A,I2,A,I2,A)', iostat=iostat, iomsg=iomsg ) '(A', vlist(1), ',I', vlist(2), ')'
      if (iostat /= 0) return

      ! now the basic output statement
      write(unit, fmt=pfmt, iostat=iostat, iomsg=iomsg) dtv%name, dtv%age
      if (iostat /= 0) return

      return

   end subroutine pwf

end module m

Upon execution even with /iface:mixed_str_len_arg compiler option,

 1John Doe           50    5

 

0 Kudos
Steven_L_Intel1
Employee
502 Views

This also applies to USEROPEN, IFLOGM (dialog support) and IMSL. Similarly, when you pass functions to Win32 API routines they must be STDCALL.

0 Kudos
Steven_L_Intel1
Employee
502 Views

I have escalated this as issue DPD200414837. Where possible, the compiler should complain if it sees that a UDDTIO procedure has non-default calling conventions.

0 Kudos
Reply