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

in DTIO, v_list size changes when format is built at runtime

jwmwalrus
New Contributor I
425 Views

Hi.

In the following code

module mod1
    implicit none
    public

contains
    function v_list_fmt(v_list) result(fmt)
        character(:), allocatable :: fmt
        integer, intent(in) :: v_list(:)

        integer :: i
        character(20) :: buf

        buf = ''

        print*,'size(v_list)=',size(v_list),new_line('')
        if (size(v_list) == 0) then
            fmt = 'dt'
            return
        endif

        write (buf, '(i0)') v_list(1)
        fmt = trim(buf)

        do i = 2, size(v_list)
            write (buf, '(i0)') v_list(i)
            fmt = fmt//','//trim(buf)
        enddo

        fmt = 'dt('//fmt//')'
    end function
end module mod1

module mod2
    use mod1

    implicit none
    private

    type, public :: child
        integer :: default = -1
    contains
        generic :: write(formatted) => write_child_formatted
        procedure :: write_child_formatted
    end type

    type, public :: parent
        type(child) :: ch
    contains
        generic :: write(formatted) => write_parent_formatted
        procedure :: write_parent_formatted
    end type

contains
    subroutine write_child_formatted(this, unit, iotype, v_list, iostat, iomsg)
        class(child), intent(in) :: this
        integer, intent(in) :: unit
        character(*), intent(in) :: iotype
        integer, intent(in) :: v_list(:)
        integer, intent(out) :: iostat
        character(*), intent(inout) :: iomsg

        if (size(v_list) > 0) then
            write (unit, '("decorated value: ",i0)', IOSTAT = iostat, iomsg = iomsg) 2 ** v_list(1)
        else
            write (unit, '("default value: ",i0)', IOSTAT = iostat, iomsg = iomsg) this%default
        endif
    end subroutine

    subroutine write_parent_formatted(this, unit, iotype, v_list, iostat, iomsg)
        class(parent), intent(in) :: this
        integer, intent(in) :: unit
        character(*), intent(in) :: iotype
        integer, intent(in) :: v_list(:)
        integer, intent(out) :: iostat
        character(*), intent(inout) :: iomsg

        write (unit, '('//v_list_fmt(v_list)//')', IOSTAT = iostat, iomsg = iomsg) this%ch
    end subroutine
end module mod2

use mod2

implicit none

type(parent) :: p

print*,p

end

 

Because the format is built at runtime, the child receives a non-empty v_list:

$ ifx -V /media/vmshare/v-list-size.f90 && ./a.out
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2025.0.4 Build 20241205
Copyright (C) 1985-2024 Intel Corporation. All rights reserved.

 Intel(R) Fortran 25.0-1205.1
GNU ld (GNU Binutils for Debian) 2.44
 size(v_list)=           0 
decorated value: 1

 

With other compilers (e.g., gfortran 14.x, flang-new 19.x), I get "default value ..." as output.

So, is ifx doing the wrong thing? Or am I wrong at relying on v_list size?

0 Kudos
4 Replies
jwmwalrus
New Contributor I
364 Views

@Ron_Green Any thoughts on this one?

0 Kudos
Steve_Lionel
Honored Contributor III
291 Views

This is clearly, to me, a bug in ifx. write_child_formatted is being called with v_list being a 1-element array, where it should be zero-sized. It doesn't astonish me that this edge case was not considered - it does greatly complicate things with run-time formats. The run-time library has its own format compiler, and it is getting this wrong.

jwmwalrus
New Contributor I
184 Views

Thanks @Steve_Lionel for the reply.

Good to know that, in general, I can rely on v_list size ---but, for now, "one" is the new "zero", hehehe.

0 Kudos
Ron_Green
Moderator
113 Views

@jwmwalrus I haven't had a chance to look at this in depth.  But since Steve says it's a bug, it's a bug.  I will open a bug report on it and keep you posted on progress.

0 Kudos
Reply