- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We recently updated to IFORT 15.0.2.179. A few of the regression tests for our code system now fail. The basic pattern is calling a function written in C with a slice of a two-dimensional character array; the compiler is not passing a pointer to the correct word in the character array. Here is a reduced example; we declare an interface to the C routine and iterate over the rows of a character array, passing the first column to the C function:
module r interface subroutine cprint ( leng, chars ) bind (c) use, intrinsic :: iso_c_binding, only : c_int, c_char integer(kind=c_int) :: leng character(kind=c_char,len=1) :: chars( leng ) end subroutine cprint end interface end module r subroutine b ( leng, chars ) use r integer :: leng, i character(len=*) :: chars( leng, 2 ) do i = 1, 2 call cprint( leng, chars(:,i) ) end do end subroutine b program a integer, parameter :: leng = 23 integer :: i character(len=1) :: chars( leng, 2 ) character(len=leng) :: buffer buffer = 'ABCDEFGHIJ' do i = 1, leng chars(i,1) = buffer(i:i) end do buffer = '1234567890' do i = 1, leng chars(i,2) = buffer(i:i) end do call b( leng, chars ) end program a
and the C++ subroutine:
#include <cstdio> extern "C" void cprint ( const int* leng, const char* chars ) { for ( int i = 0; i < *leng; ++i ) { putc( chars, stdout ); } putc( '\n', stdout ); fflush( stdout ); }
I expect this to print:
ABCDEFGHIJ 1234567890
But instead I get:
ABCDEFGHIJ ABCDEFGHIJ
If I look at the assembly code for subroutine b, it appears that the correct address for chars(:,i) is not being computed; it just uses the same address for each iteration.
Variations: If I replace character(len=*) with character(len=1) in subroutine b, the correct strings are printed by cprint. If I leave in (len=*) but call a Fortran print subroutine with the same arguments, the correct strings are printed.
I tried my example program with ifort 14.0.4.237 and it also prints the incorrect strings. But, our main program, which is lot larger, works correctly. Kind of odd.
Thanks,
Allen
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your example does not pass an array slice to C.
Did you mean to use:
call
b( leng, chars(:,1) )
call
b( leng, chars(:,2) )
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm. It's supposed to pass the 2D array to subroutine b and then a slice of that is passed on to the C function cprint. Does it not do that?
Allen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Interesting. Declaring "chars" in subroutine b as len=1 rather than len=* gives the correct behavior, even though they should be the same here. We'll take a look.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can go back to version 12.1 and still see the bad behavior. Which compiler version did you use where you got the results you like?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Our main code has had this idiom for a long time, probably since version 11, and it has always worked until 15.0. The compiler has never complained.
We've been reading the Fortran standard and it probably is an error to use len=*, but it has worked as-is for a long time.
Thanks,
Allen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, it's not an error to use len=* - b is not a bind(c) routine. I escalated this as issue DPD200366425 - I tried all compilers back to 12.1 and got the same bad results. Very puzzling. Removing bind(c) from cprint (which is declared correctly) also corrects the behavior.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This has been fixed for a release later this year.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page