- 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