- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am not sure if this is legal to do. I get a seg fault in the following code where i use a procedure, say A, passed as an argument to another procedure, say B. Procedure A has a argument which is an unlimited polymorphic argument.
Here is the test case:
I am not sure if this is legal to do. I get a seg fault in the following code where i use a procedure, say A, passed as an argument to another procedure, say B. Procedure A has a argument which is an unlimited polymorphic argument.
Here is the test case:
[fortran]module DTCompontentPointer
implicit none
type A
integer numB
procedure(),pointer,nopass :: f=>null()
contains
procedure :: init => init
end type A
contains
subroutine init(this,numB,foo)
class(A),intent(inout),target :: this
integer, intent(in) :: numB
external :: foo
this%numB = numB
this%f => foo
end subroutine init
end module DTCompontentPointer
module Temp
implicit none
contains
subroutine foo1(val)
integer :: val
integer :: ival
!real :: upoly
print*,'Value=',val
print*,'ThisWorks'
end subroutine foo1
subroutine foo2(val,upoly)
integer :: val
class(*):: upoly
!real :: upoly
print*,'Value=',val
print*,'This seg faults on Next Line'
select type(upoly)
type is(integer)
print*,'upoly is integer with value=',upoly
type is(real)
print*,'upoly is real with value=',upoly
end select
end subroutine foo2
end module Temp
program Test
use DTCompontentPointer
use Temp
type(A):: C
integer :: ival
real :: rval
call C%init(5,foo1)
ival=10
call C%f(ival)
call C%init(6,foo2)
rval=8.0
call C%f(ival,rval)
end program Test[/fortran]
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have taken a quick look at this. The fundamental issue is that foo2 accepts an unlimited polymoprphic but there is no explicit interface visible to the caller saying so. You then pass it a REAL, which doesn't include the information needed to resolve the CLASS(*). Since you have gone to some lengths to hide the interface of the pointer procedure, the compiler can't validate this for you.
If you're going to be calling a procedure that requires an explicit interface, then you must provide one.
If you're going to be calling a procedure that requires an explicit interface, then you must provide one.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So, how is foo differenet from foo2. Both of them do not have explicit interface. I even tried passing a CLASS(*) object as a second argument to the foo2. I still get segfault. Have a look at this code
[fortran]module DTCompontentPointer
implicit none
type A
integer numB
procedure(),pointer,nopass :: f=>null()
contains
procedure :: init => init
end type A
contains
subroutine init(this,numB,foo)
class(A),intent(inout),target :: this
integer, intent(in) :: numB
external :: foo
this%numB = numB
this%f => foo
end subroutine init
end module DTCompontentPointer
module Temp
implicit none
contains
subroutine foo1(val)
integer :: val
integer :: ival
!real :: upoly
print*,'Value=',val
print*,'ThisWorks'
end subroutine foo1
subroutine foo2(val,upoly)
integer :: val
class(*):: upoly
!real :: upoly
print*,'Value=',val
print*,'This seg faults on Next Line'
select type(upoly)
type is(integer)
print*,'upoly is integer with value=',upoly
type is(real)
print*,'upoly is real with value=',upoly
end select
end subroutine foo2
end module Temp
program Test
use DTCompontentPointer
use Temp
type(A):: C
integer :: ival
class(*),pointer :: rvalupoly
real :: rval
call C%init(5,foo1)
ival=10
call C%f(ival)
call C%init(6,foo2)
rval=8.0
allocate(rvalupoly,source=rval)
select type(rvalupoly)
type is(integer)
print*,'rvalupoly is integer with value=',rvalupoly
type is(real)
print*,'rvalupolyis real with value=',rvalupoly
end select
call C%f(ival,rvalupoly)
end program Test[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
foo doesn't have a upoly argument and doesn't require an explicit interface. It doesn't matter that you pass a upoly - what matters is that the compiler can see, at the point of the call, that the called procedure is expecting a polymorphic argument. This is one of the cases that requires an explicit interface to be visible to the caller.
You can't fudge this with the approach you are taking. The procedure pointer f has no interface, so it is treated as if it was just an ordinary external routine. There's no information the compiler can use to pass what foo2 wants.
You can't fudge this with the approach you are taking. The procedure pointer f has no interface, so it is treated as if it was just an ordinary external routine. There's no information the compiler can use to pass what foo2 wants.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks. I got it. I was using an explicit interface. I was experimenting with this other appraoch. Did not knew that explicit interface is needed in case of polymorphic arguments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is what the standard now says about this:
19 1 A procedure other than a statement function shall have an explicit interface if it is referenced and
20 (1) a reference to the procedure appears
21 (a) with an argument keyword (12.5.2), or
22 (b) in a context that requires it to be pure,
23 (2) the procedure has a dummy argument that
24 (a) has the ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE,
25 or VOLATILE attribute,
26 (b) is an assumed-shape array,
27 (c) is a coarray,
28 (d) is of a parameterized derived type, or
29 (e) is polymorphic,
30 (3) the procedure has a result that
31 (a) is an array,
32 (b) is a pointer or is allocatable, or
33 (c) has a nonassumed type parameter value that is not a constant expression,
34 (4) the procedure is elemental, or
35 (5) the procedure has the BIND attribute.
19 1 A procedure other than a statement function shall have an explicit interface if it is referenced and
20 (1) a reference to the procedure appears
21 (a) with an argument keyword (12.5.2), or
22 (b) in a context that requires it to be pure,
23 (2) the procedure has a dummy argument that
24 (a) has the ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE,
25 or VOLATILE attribute,
26 (b) is an assumed-shape array,
27 (c) is a coarray,
28 (d) is of a parameterized derived type, or
29 (e) is polymorphic,
30 (3) the procedure has a result that
31 (a) is an array,
32 (b) is a pointer or is allocatable, or
33 (c) has a nonassumed type parameter value that is not a constant expression,
34 (4) the procedure is elemental, or
35 (5) the procedure has the BIND attribute.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page