Community
cancel
Showing results for 
Search instead for 
Did you mean: 
martymike
Beginner
102 Views

error with deferred size character array with fixed length

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
102 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
Beginner
102 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
102 Views

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

0 Kudos
martymike
Beginner
102 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
102 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
Black Belt
102 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
102 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
Black Belt
102 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
102 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
102 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
Beginner
102 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
102 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
102 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