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))
Link Copied
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.
I have specified /standard-semantics. I should have mentioned that. We do that for everything so it slipped my mind to mention it.
It works fine when I try it. Perhaps you can show me a small but complete example that shows otherwise?
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.
Ok - this is more complicated than what you showed earlier. There does seem to be a problem - we'll look into it.
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.
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.
I see. I just noted that subtitle also has SAVE specified. How does that interact with automatic reallocation?
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.
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.
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?
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.
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.
For more complete information about compiler optimizations, see our Optimization Notice.