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

String array values become null when passing

Chaudhry__Ross
Beginner
392 Views

When passing an array of strings to a subroutine, some of the values are being set to null (ichar=0). Consider the following example code:

! -- Module to declare variable
module my_data
   implicit none

   ! -- Declare as deferred-length allocatable array
   character(len=:), dimension(:), allocatable :: str_array
end module my_data

! -- Module to call subroutine
module my_subs
   implicit none

contains
subroutine a(str_array)
   character(len=*), dimension(:), intent(IN) :: str_array
   integer :: i, j
   character :: c

   do i=1,size(str_array)
      do j=1,len_trim(str_array(i))
         c = str_array(i)(j:j)

         ! -- Write i, j, character, and int representation
         write(*,*) 'In call: ', i, j, ' "'//c//'", ichar = ', ichar(c)
      enddo
   enddo
end subroutine a
end module my_subs

! -- Main program
program main
   use my_data, only : str_array
   use my_subs, only : a
   implicit none
   integer, parameter :: strlen = 200
   integer :: N, i, j
   character :: c

   ! -- Size of str array
   N = 2

   ! -- Allocate str_array, syntax from https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/287349
   allocate(character(strlen) :: str_array(N))

   ! -- Set both to the same string
   str_array = 'abc'

   do i=1,size(str_array)
      do j=1,len_trim(str_array(i))
         c = str_array(i)(j:j)

         ! -- Write i, j, character, and int representation
         write(*,*) 'In main: ', i, j, ' "'//c//'", ichar = ', ichar(c)
      enddo
   enddo

   call a(str_array)
end program main

After allocating and setting the character array, I pass it to a subroutine. Before the subroutine call and within the subroutine, the elements of the string array are output. For some versions of ifort, the second string's original elements are set to the null character, with the size and length preserved.

With most Intel (or GCC or PGI), I get what I expect:

chaud106@ln0005 [~/Testing] % ifort --version && ifort -check all -warn all main.f90 && ./a.out
ifort (IFORT) 15.0.3 20150407
Copyright (C) 1985-2015 Intel Corporation.  All rights reserved.

 In main:            1           1  "a", ichar =           97
 In main:            1           2  "b", ichar =           98
 In main:            1           3  "c", ichar =           99
 In main:            2           1  "a", ichar =           97
 In main:            2           2  "b", ichar =           98
 In main:            2           3  "c", ichar =           99
 In call:            1           1  "a", ichar =           97
 In call:            1           2  "b", ichar =           98
 In call:            1           3  "c", ichar =           99
 In call:            2           1  "a", ichar =           97
 In call:            2           2  "b", ichar =           98
 In call:            2           3  "c", ichar =           99

However, with Intel versions 17.0.4 to 18.0.0, I get the nullification:

chaud106@ln0005 [~/Testing] % ifort --version && ifort -check all -warn all main.f90 && ./a.out
ifort (IFORT) 18.0.0 20170811
Copyright (C) 1985-2017 Intel Corporation.  All rights reserved.

 In main:            1           1  "a", ichar =           97
 In main:            1           2  "b", ichar =           98
 In main:            1           3  "c", ichar =           99
 In main:            2           1  "a", ichar =           97
 In main:            2           2  "b", ichar =           98
 In main:            2           3  "c", ichar =           99
 In call:            1           1  "a", ichar =           97
 In call:            1           2  "b", ichar =           98
 In call:            1           3  "c", ichar =           99
 In call:            2           1  "", ichar =            0
 In call:            2           2  "", ichar =            0
 In call:            2           3  "", ichar =            0

This issue was also posted at https://stackoverflow.com/questions/51523524/string-array-being-nullified-when-passing, where the conclusion seems to be that it's a problem with the Intel compiler. It does not appear for Intel 18.0.3, which I don't have access to on my cluster. For now, I am using a workaround where I declare str_array using `str_array(:) = ...`. I am posting here for several reasons:

  1. Is this indeed a compiler bug, or am I formatting something (perhaps the dummy declaration) incorrectly?
  2. Let the Intel developers know this was a problem with the current compiler, perhaps to add it to their internal test suite.
  3. How does this relate (if at all) to automatically allocating the LHS when shapes differ? My understanding is that no reallocation should occur because the string `abc` will be expanded to whatever shape `str_array` currently has. However, the change occurred right around when Intel included this portion of the 2003 standard.
0 Kudos
1 Reply
FortranFan
Honored Contributor II
392 Views

My feedback:

  1. This is indeed a compiler bug in certain versions of Intel Fortran compiler such as 17.0U4, 17.0U5, 18.0U1, 18.0U2.  As you noted, 18.0U3 and 19.0 Beta U1 does not show the problem.  Your code is standard-conforming in my opinion.
  2. You need to submit support request at https://supporttickets.intel.com/?lang=en-US, that is the only way to be sure Intel developers are informed.
  3. You and I and none of the readers can possibly know the root cause of the issue but that shouldn't matter.  You have standard-conforming code which should generate expected results but which doesn't with certain versions as mentioned in 1, that's the bottomline.
0 Kudos
Reply