- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I have a problem with type extension (I think). Look at the following problem (and the code below):
We have a variable a1, extended to a variable a2, and then extended to a3. All of this variables have a unique type bound procedure called "copy", that it is overwritten in the succesive classes (that is, "copy" member of a3 overwrites "copy" member of a2, and so on).
When I compile the code with Intel Fortran Compiler version 11.1.069, it appeas the following:
prueba.f90(110): error #6618: The INTERFACE/CONTAINS stack is full. This means that modules are being 'used' in a circular way.
end program main
^
compilation aborted for prueba.f90 (code 1)
If we comment the "private" statements the problem dissapears, but I do not want to do that because I want to hide the members of the classes.
Is there a mistake in the program? Is it a compiler bug (maybe already reported)? I have found something similar in this forum entitled "Function returning pointer to class data"
Any idea will be welcome.
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
module class_a1
implicit none
private
type , public :: a1
private
integer :: x
contains
procedure :: copy => a1_copy
end type a1
contains
subroutine a1_copy( this , b )
implicit none
class( a1 ) , intent( inout ) :: this
class( a1 ) , intent( in ) :: b
this%x = b%x
end subroutine a1_copy
end module class_a1
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
module class_a2
use class_a1
implicit none
private
type , extends( a1 ) , public :: a2
private
integer :: y
contains
procedure :: copy => a2_copy
end type a2
contains
subroutine a2_copy( this , b )
implicit none
class( a2 ) , intent( inout ) :: this
class( a1 ) , intent( in ) :: b
select type( b )
type is( a2 )
call this%a1%copy( b%a1 )
this%y = b%y
end select
end subroutine a2_copy
end module class_a2
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
module class_a3
use class_a1
use class_a2
implicit none
private
type , extends( a2 ) , public :: a3
private
integer :: z
contains
procedure :: copy => a3_copy
end type a3
contains
subroutine a3_copy( this , b )
implicit none
class( a3 ) , intent( inout ) :: this
class( a1 ) , intent( in ) :: b
select type( b )
type is( a3 )
call this%a2%copy( b%a2 )
this%z = b%z
end select
end subroutine a3_copy
end module class_a3
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
program main
use class_a3
implicit none
type( a3 ) :: ei
end program main
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
We have a variable a1, extended to a variable a2, and then extended to a3. All of this variables have a unique type bound procedure called "copy", that it is overwritten in the succesive classes (that is, "copy" member of a3 overwrites "copy" member of a2, and so on).
When I compile the code with Intel Fortran Compiler version 11.1.069, it appeas the following:
prueba.f90(110): error #6618: The INTERFACE/CONTAINS stack is full. This means that modules are being 'used' in a circular way.
end program main
^
compilation aborted for prueba.f90 (code 1)
If we comment the "private" statements the problem dissapears, but I do not want to do that because I want to hide the members of the classes.
Is there a mistake in the program? Is it a compiler bug (maybe already reported)? I have found something similar in this forum entitled "Function returning pointer to class data"
Any idea will be welcome.
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
module class_a1
implicit none
private
type , public :: a1
private
integer :: x
contains
procedure :: copy => a1_copy
end type a1
contains
subroutine a1_copy( this , b )
implicit none
class( a1 ) , intent( inout ) :: this
class( a1 ) , intent( in ) :: b
this%x = b%x
end subroutine a1_copy
end module class_a1
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
module class_a2
use class_a1
implicit none
private
type , extends( a1 ) , public :: a2
private
integer :: y
contains
procedure :: copy => a2_copy
end type a2
contains
subroutine a2_copy( this , b )
implicit none
class( a2 ) , intent( inout ) :: this
class( a1 ) , intent( in ) :: b
select type( b )
type is( a2 )
call this%a1%copy( b%a1 )
this%y = b%y
end select
end subroutine a2_copy
end module class_a2
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
module class_a3
use class_a1
use class_a2
implicit none
private
type , extends( a2 ) , public :: a3
private
integer :: z
contains
procedure :: copy => a3_copy
end type a3
contains
subroutine a3_copy( this , b )
implicit none
class( a3 ) , intent( inout ) :: this
class( a1 ) , intent( in ) :: b
select type( b )
type is( a3 )
call this%a2%copy( b%a2 )
this%z = b%z
end select
end subroutine a3_copy
end module class_a3
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
program main
use class_a3
implicit none
type( a3 ) :: ei
end program main
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
コピーされたリンク
6 返答(返信)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
This appears to be a compiler bug - I will report it to the developers. The workaround you found can be used for now, otherwise I don't know what to suggest.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
As a workaround, instead of commenting, remove the "private" statement within the derived types and add as an attribute to every component, as in:
!-------------------------------------------------------------------------------
...
type , public :: a1
integer, private :: x
contains
procedure :: copy => a1_copy
end type a1
...
!-------------------------------------------------------------------------------
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Your copy proceedure pointer points to a function taking 2 arguments. Whereas your use calls with one argument.
In a2_copy try changing:
call this%a1%copy( b%a1 )
to
call this%a1%copy( this, b%a1 )
In a3_copy try changing:
call this%a2%copy( b%a2 )
to
call this%a2%copy( this, b%a2 )
Jim Dempsey
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Jim,
The call is correct. A type-bound procedure has an implicit first argument of the derived type value of which it is a component, unless NOPASS is specified in the declaration.
This issue has been escalated as DPD200152345.
The call is correct. A type-bound procedure has an implicit first argument of the derived type value of which it is a component, unless NOPASS is specified in the declaration.
This issue has been escalated as DPD200152345.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Thanks for your suggestion! Now it is working. I suppose that in the next release this problem will be solved. Meanwhile, as a workaround, I will put the private attribute to every component in the derived type.
Thanks for all the replays.
Thanks for all the replays.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
This has been fixed for the next major release.
