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

runtime error resp. wrong behaviour with polymorphic function

johnyb_
New Contributor I
567 Views

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.

[fortran]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[/fortran]

This results in:

[plain]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>[/plain]


Johny

0 Kudos
3 Replies
Steven_L_Intel1
Employee
567 Views
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.
0 Kudos
johnyb_
New Contributor I
567 Views

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:

[fortran]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[/fortran]


this should print "01234" each time, but:

[plain]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>[/plain]


Johny

0 Kudos
Steven_L_Intel1
Employee
567 Views

The problem was fixed in the 13.0 compiler.

0 Kudos
Reply