Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

error with deferred size character array with fixed length

martymike
Novice
1,790 Views

I have a module that does this (among other things):

module tryit
implicit none

character(len=:),allocatable,dimension(:),save :: subtitle

contains

subroutine setSubTitle(lines)
character(len=*),dimension(:) :: lines
subtitle=lines
end subroutine setSubTitle

subroutine getSubTitle ( lines )
character(len=*),dimension(:),intent(out) :: lines
if (allocated(subtitle)) lines = subtitle
end subroutine getSubTitle

end

This works fine. But I had a reason to consider making the length of subtitle a constant, e.g.:

character(len=60),allocatable,dimension(:),save :: subtitle

This crashes on the first reference to subtitle *after* the assignment. Should this work?

In each case I tried the actual argument passed as lines was a static array, e.g.:

character(len=220),save :: buffer(20)

call setSubTitles(buffer(3:9))

 

0 Kudos
13 Replies
Steven_L_Intel1
Employee
1,790 Views

Here's what's happening. The ifort default is to not enable automatic reallocation on assignments to allocatable arrays. You have to use /assume:realloc_lhs or /standard-semantics to get this F2003 feature. However, if you use deferred-length character allocatables, then we do enable reallocation because that syntax was new in F2003 and it's what most people are expecting. So when you changed the : to a 60, you turned off the automatic reallocation.

Set the project property Fortran > Language > Enable F2003 Semantics to Yes and you should be fine.

0 Kudos
martymike
Novice
1,790 Views

I have specified /standard-semantics. I should have mentioned that. We do that for everything so it slipped my mind to mention it.

0 Kudos
Steven_L_Intel1
Employee
1,790 Views

It works fine when I try it. Perhaps you can show me a small but complete example that shows otherwise?

0 Kudos
martymike
Novice
1,790 Views

tryit.f90:

==========================================================

module tryit2
implicit none

character(len=40),allocatable,dimension(:),save ::  subtitle

contains

subroutine setSubTitle(lines)
character(len=*),dimension(:) :: lines
subtitle=lines
call printem
end subroutine setSubTitle

subroutine getSubTitle ( lines )
character(len=*),dimension(:),intent(out) :: lines
if (allocated(subtitle)) lines = subtitle
end subroutine getSubTitle

subroutine printem
integer i
print *,'subtitle',len(subtitle),size(subtitle)
do i=1,size(subtitle)
   print '('' "'',a,''"'')',subtitle(i)
enddo
print *,'-------------------------------------------'
end subroutine printem

end

==========================================================

main.f90:

==========================================================

use tryit2
character(len=10),dimension(3) :: t=['there is a',  ' great dea',  'l to show.']
character(len=12),dimension(4) :: u=['here is anot','her view of ','things to se','e and to do.']
character(len=4),dimension(4) :: v=['matt','mark','luke','john']
character(len=16),dimension(4) :: a


call setsubtitle(t)
call getsubtitle(a)
call printit
call setsubtitle(u)
call getsubtitle(a)
call printit
call setsubtitle(v)
call getsubtitle(a)
call printit

continue

contains

subroutine printit
integer i
print *,'retrieved',len(a),size(a)
do i=1,size(a)
   print '('' "'',a,''"'')',a(i)
enddo
print *,'-------------------------------------------'
end subroutine printit

end

==========================================================

compiler options (from Visual Studio 2013):

==========================================================

/nologo /debug:full /Od /extend_source:132 /noaltparam /standard-semantics /warn:declarations /warn:unused /warn:ignore_loc /warn:truncated_source /warn:interfaces /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc120.pdb" /traceback /check:bounds /check:stack /libs:dll /threads /dbglibs /c

==========================================================

I'm still running the initial release of IVF 15, so perhaps this is something that has been fixed. We also have projects building with IVF 12.0, and I tried it there. It crashes there, too, in the same place, although the contents of subtitle just before the crash (according to the debugger) are different.

0 Kudos
Steven_L_Intel1
Employee
1,790 Views

Ok - this is more complicated than what you showed earlier. There does seem to be a problem - we'll look into it.

0 Kudos
mecej4
Honored Contributor III
1,790 Views

I think that the program has a bug, but I don't quite understand the author's intent. The first call to setSubTitle causes "subtitle" to be an array with 3 elements. The subsequent call to getSubTitle tries to get an array with 4 elements through an assignment statement in which an array of extent 4 is assigned equal to an array of extent 3. I am surprised that /check:bounds did not detect this.

0 Kudos
Steven_L_Intel1
Employee
1,790 Views

Not a bug - the F2003 automatic reallocation feature will cause the 3-element array to be deallocated and a 4-element one allocated. It doesn't get that far, though - the initial assignment is corrupting memory.

0 Kudos
mecej4
Honored Contributor III
1,790 Views

I see. I just noted that subtitle also has SAVE specified. How does that interact with automatic reallocation?

0 Kudos
Steven_L_Intel1
Employee
1,790 Views

The SAVE is redundant as subtitle is a module variable. SAVE for an ALLOCATABLE simply means that it remains defined when it goes out of scope. This would be meaningful if you had this as a procedure local variable. The practical implementation is that the descriptor is static.

0 Kudos
Steven_L_Intel1
Employee
1,790 Views

I determined that the program works correctly with the 16.0 compiler, so it looks as if the bug is already fixed. A workaround is to add:

if (allocated(subtitle)) deallocate(subtitle)
allocate (subtitle(size(lines)))

before the assignment.

0 Kudos
martymike
Novice
1,790 Views

Thank you. Steve.

I take it, then, that it may not be fixed in any later updates to IVF 15?

Also, regarding the SAVE specification, do I understand correctly that it is redundant in IVF, but that in the standard it might not be?

0 Kudos
Steven_L_Intel1
Employee
1,790 Views

I am pretty sure it won't be in the final 15.0 update.

The standard now specifies that variables in a module automatically have SAVE. Earlier standards (before F2003?) said that module variables remained defined as long as there was at least one active "instance" of a use of the module, something that comes from COMMON in the past. But nobody implements it that way and the standard was changed to simply say module variables have SAVE.

0 Kudos
JVanB
Valued Contributor II
1,790 Views

There was a constraint in F95 that resulted in (non-POINTER, non-ALLOCATABLE) instances of a UDT with default initialization as a module variable automatically having the SAVE attribute because if they didn't have the SAVE attribute the code would be nonconforming. It seems to me that there was a similar constraint about module variables with the ALLOCATABLE attribute in one of the corrigenda to F95, and for the same reason: the Fortran processor was required to take active steps when such a variable went out of scope and back in (re-initialization of UDTs with default initializers and deallocation of ALLOCATABLEs) which would require the Fortran processor to keep track of when modules went into and out of scope. Unfortunately I can't find my hardcopy of the corrigenda so I can't verify that for ALLOCATABLE module variables, as here, F95 required the SAVE attribute.

 

0 Kudos
Reply