Automatic allocation of allocatable components of a type
When using the assignment B = A for derived types, it seems it is not necessary to allocate any allocatable
components that B may contain. Is this correct?
Consider the following example:
PROGRAM MAIN IMPLICIT NONE
TYPE T_L INTEGER,ALLOCATABLE :: L(:) END TYPE T_L TYPE A
TYPE(T_L),ALLOCATABLE :: SETS(:) END TYPE A TYPE(A) :: U,V
ALLOCATE(U%SETS(2)) ALLOCATE(U%SETS(1)%L(4)) ALLOCATE(U%SETS(2)%L(6)) U%SETS(1)%L = [1,2,3,4] U%SETS(2)%L =
[5,6,7,8,9,0]
V = U WRITE(*,*) V%SETS(1)%L(:) WRITE(*,*) V%SETS(2)%L(:)
END PROGRAM
MAIN
This program initializes V correctly - which puzzles me a bit, I would have expected an access violation
error. This is very convenient; but are there any limitations regarding this automatic allocation for allocatable
components of derived type variables that I should be aware of?
Now - if U and V are normal allocatable (and
not derived types) variables, this doesn't work of course.
I am using IVF 10.1
Thanks!
Olivier
| |
Re: Automatic allocation of allocatable components of a type
This is correct and a feature of Fortran 2003.
Another related feature of Fortran 2003 is for allocatable
arrays, where you could say:
integer, allocatable, dimension(:) :: a
a = [3,4,5]
and a would get automatically allocated to the proper shape, deallocating any previous allocation. In Intel Fortran,
this behavior is NOT the default and requires an option /assume:realloc_lhs. However, the use you described with the
derived type components does not require the option.
Steve
Attaching or including files in a post
Doctor Fortran blog
@DoctorFortran on Twitter | |
Re: Automatic allocation of allocatable components of a type
This is correct and a feature of Fortran 2003.
Another related
feature of Fortran 2003 is for allocatable arrays, where you could say:
integer, allocatable, dimension(:) :: a
a = [3,4,5]
and a would get automatically allocated to the proper shape, deallocating any previous allocation. In Intel Fortran,
this behavior is NOT the default and requires an option /assume:realloc_lhs. However, the use you described with the
derived type components does not require the option.
wOW... That's very neat. Thanks a lot Steve.
Olivier
| |
Re: Automatic allocation of allocatable components of a type
This is correct and a feature of Fortran 2003.
Another related
feature of Fortran 2003 is for allocatable arrays, where you could say:
integer, allocatable, dimension(:) :: a
a = [3,4,5]
and a would get automatically allocated to the proper shape, deallocating any previous allocation. In Intel Fortran,
this behavior is NOT the default and requires an option /assume:realloc_lhs. However, the use you described with the
derived type components does not require the option.
Steve,
While obviously convenient - is this also not a bit dangerous?
What happens if you
erroneously do something like
a=[3,4,5]
... a=[3,4,5,10]
where the use of a
4-element array is a bug (lets say due to bug)
Then my understanding is that F-2003 reallocates array a
"behind your back", which would make it harder to catch this bug. Conversely F-95 would generate an access error and
you'd have a pretty clear indication of a bug.
I suppose this comes down to safety vs convenience, I am not
really criticizing, just contemplating ;-)
| |
Re: Automatic allocation of allocatable components of a type
Well, maybe it's not a bug? I agree that many programs would not want this behavior (especially as it adds
run-time cost) which is why we turn it off by default. Unfortunately, we don't offer a way to detect the error if you
have the feature disabled - that second assignment of yours would have unpredictable results.
Steve
Attaching or including files in a post
Doctor Fortran blog
@DoctorFortran on Twitter | |
Re: Automatic allocation of allocatable components of a type
Steve,
While obviously convenient - is this also not a bit dangerous?
What happens if you
erroneously do something like
a=[3,4,5]
... a=[3,4,5,10]
where the use of a
4-element array is a bug (lets say due to bug)
Then my understanding is that F-2003 reallocates array a
"behind your back", which would make it harder to catch this bug. Conversely F-95 would generate an access error and
you'd have a pretty clear indication of a bug.
I suppose this comes down to safety vs convenience, I am not
really criticizing, just contemplating ;-)
If you know the size beforehand, you can specify the dimensions in the declaration. Then, I'd expect that
the "bug" will be detected.
regards, Thomas
| |
Re: Automatic allocation of allocatable components of a type
Well, maybe it's not a bug? I agree that many programs would not
want this behavior (especially as it adds run-time cost) which is why we turn it off by default. Unfortunately, we
don't offer a way to detect the error if you have the feature disabled - that second assignment of yours would have
unpredictable results.
Perhaps a new attribute would be in order.
integer, reallocatable_lhs, dimension(:) :: a
Jim Dempsey
Blog: The Parallel Void
www.quickthreadprogramming.com | |
Re: Automatic allocation of allocatable components of a type
Interesting idea, Jim, but that's not the way we usually handle such things, especially when the behavior is specified
by the standard. I know at least one other major compiler vendor that does just what we do in this case - require a
switch to get the realloc behavior.
Steve
Attaching or including files in a post
Doctor Fortran blog
@DoctorFortran on Twitter | |
Re: Automatic allocation of allocatable components of a type
Sorry to hijack this thread, but I have a problem regarding exactly the mentioned functionality in v11.1.035
Above mentioned automatic allocation of type members seems to be broken in cases where the original allocated array is
created using (/ /) or [ ] syntax instead of using allocate().
The code below results in an access
violation during the write statement. It works fine when the allocate statement is uncommented. /assume:realloc_lhs is
set during compile.
Is that expected behavior or a compiler bug?
regards, Thomas
PROGRAM AUTOALLOC
!
TYPE :: tA
INTEGER,ALLOCATABLE,DIMENSION(:) :: IDATA
END TYPE
TYPE :: tB
TYPE (tA) :: A
END TYPE
!
TYPE (tA) :: A
TYPE (tB) :: B
! Allocate(IData(3))
A%IData = (/ 1, 2, 3 /)
B%A = A
WRITE (*,*) B%A%IData
END PROGRAM AUTOALLOC
| |
Re: Automatic allocation of allocatable components of a type
Steve, (re: re-allocatable_lhs)
The point being not so much of what the behavior is as to when/how the
behavior is enabled.
The compiler switch has global ramifications whereas an attribute restricts behavior to
specific instances. Who among us has taken legacy code (F95 in this case) forward in an incremental manner? It would
seem to me that an attribute would be preferred over an all or nothing approach.
The standards committee
goofed (at least was short sighted and didn't look backwards while looking forward).
Also, the re-allocatable
lhs attribute should (maybe it is) have a required flag bit in the array descriptor to indicate if it can/cannot be
automatically reallocated.
Has anyone compiled statistics on how much time was/is/will be wasted tracking
down programming errors that are now hidden by the compiler? I hope, at least, there is a diagnostic report option to
report on the re-allocations (both at compile time and at run time).
Jim
Blog: The Parallel Void
www.quickthreadprogramming.com | | |