runtime error resp. wrong behaviour with polymorphic function

runtime error resp. wrong behaviour with polymorphic function

I do not do it on purpose :-/, but I have another problem with a function that accepts an unlimited polymorphic argument.

The real code that shows the error produces XML files and this small routine formats items depending on their type. In the real code the SELECT TYPE has many more TYPE IS blocks.

I have no problems if the "value" argument is of any type except character. If "value" is a character, the intial code produced a runtime error (the "notok" function). I got around this by changing the order of the arguments (the "OK" function).
However the "OK" function emits an empty string if the actual argument for "value" is a component of a derived type, which is the case for the real code where I found this problem.

module mtest contains function to_xml_ok( name, fmt_value, value) character(:), allocatable :: to_xml_ok character(len=*), intent(in) :: name class(*) , intent(in) :: value character(len=*), intent(in) :: fmt_value character(:), allocatable :: my_fmt character(len=100) :: temp my_fmt = "(''," // trim(fmt_value) // ",'' )" select type(value) class is (character(len=*)) write(temp, fmt=my_fmt) name, trim(value), name end select to_xml_ok = trim(Temp) end function function to_xml_notok( name, value, fmt_value) character(:), allocatable :: to_xml_notok character(len=*), intent(in) :: name class(*) , intent(in) :: value character(len=*), intent(in) :: fmt_value character(:), allocatable :: my_fmt character(len=100) :: temp my_fmt = "(''," // trim(fmt_value) // ",'' )" select type(value) class is (character(len=*)) write(temp, fmt=my_fmt) name, trim(value), name end select to_xml_notok = trim(Temp) end function end module mtest program test use mtest type t_test character(len=10) :: s end type character(len=10) :: c type(t_test) :: v c = '01234' v%s = '01234' print *, to_xml_ok ( 'char', 'A10', c ) print *, to_xml_ok ( 'char', 'A10', v%s ) print *, to_xml_notok( 'char', c, 'A') end program

This results in:

C:TEMP>ifort test.f90 Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.1.4.325 Build 20120410 Copyright (C) 1985-2012 Intel Corporation. All rights reserved. Microsoft Incremental Linker Version 10.00.40219.01 Copyright (C) Microsoft Corporation. All rights reserved. -out:test.exe -subsystem:console test.obj C:TEMP>test 01234forrtl: info (58): format syntax error at or near forrtl: severe (62): syntax error in format, unit -5, file Internal Formatted Write or ENCODE Image PC Routine Line Source test.exe 00449AA0 Unknown Unknown Unknown test.exe 004470D3 Unknown Unknown Unknown test.exe 0041C38F Unknown Unknown Unknown test.exe 00410577 Unknown Unknown Unknown test.exe 0040F8BA Unknown Unknown Unknown test.exe 00409182 Unknown Unknown Unknown test.exe 004014F3 Unknown Unknown Unknown test.exe 0044FD93 Unknown Unknown Unknown test.exe 00435D3F Unknown Unknown Unknown kernel32.dll 7C817067 Unknown Unknown Unknown C:TEMP>

Johny

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

Very interesting. The order of the arguments seems to matter. Note that you swap the order of the fmt_value and value arguments in the call to to_xml_notok. When that routine is called, it gets the wrong length for fmt_value leading to incorrect construction of the format string. If you reverse the order of these arguments to match that of to_xml_tok, it works.

I will let the developers know about this. Issue ID is DPD200233842. Thanks for the example.

Steve - Intel Developer Support

Hi Steve,

yes, the order of the arguments seems to matter, and swappingfmt_value and value around was my first attempt to work around the problem.
But to_xml_ok only works if value is a"simple" character variable. In my example, the second call of to_xml_ok with a component of a derived type does not crash, as the format string is correctly passed. However instead of printing 01234only an empty string is printed.

I have tried to isolate this further and this example shows the problem more clearly:

module mtest

    contains

        subroutine print_poly( value )

            class(*), intent(in) :: value
            select type(value)

                class is (character(len=*))

                    print *, ">",trim(value)

            end select

        end subroutine
end module mtest
program test

    use mtest

    type t_test

        character(len=10) :: s

    end type 
    character(len=10)   :: c

    type(t_test)        :: v
    c   = '01234'

    v%s = '01234'
    call print_poly( c )

    call print_poly( v%s )
end program

this should print "01234" each time, but:

C:TEMP>ifort test.f90

Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.1.4.325 Build 20120410

Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.
Microsoft  Incremental Linker Version 10.00.40219.01

Copyright (C) Microsoft Corporation.  All rights reserved.
-out:test.exe

-subsystem:console

test.obj
C:TEMP>test

 >01234

 >
C:TEMP>

Johny

Johny

The problem was fixed in the 13.0 compiler.

Steve - Intel Developer Support

Lascia un commento

Eseguire l'accesso per aggiungere un commento. Non siete membri? Iscriviti oggi