- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am trying to construct a static array of procedure pointers like this:
abstract interface function USERFUNC_int (arg) integer USERFUNC_int integer, intent(IN) :: arg end function USERFUNC_int end interface procedure(USERFUNC_int), pointer :: pcfs(100)
but the compiler complains about the "(":
error #5082: Syntax error, found '(' when expecting one of: , <END-OF-STATEMENT> ; =>
procedure(USERFUNC_int), pointer :: pcfs(100)
It is possible to declare a static array of procedure pointers? I am using ifort 13.1.3.0.
Thanks,
Rak
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
...
And assume the user wishes to pass the "this" pointer...
Could the user then explicitly declare the "this" pointer in the function interface?...
Jim,
Is the functionality shown in the code below what you're asking about? It is standard Fortran.
module pcf_mod type :: ARRPROCPOINTER procedure(USERFUNC_int), pointer, pass(this) :: pcf end type ARRPROCPOINTER abstract interface function USERFUNC_int (arg, this) import :: ARRPROCPOINTER integer USERFUNC_int integer, intent(IN) :: arg class(ARRPROCPOINTER) :: this end function USERFUNC_int end interface type(ARRPROCPOINTER) :: pcfs(100) end module pcf_mod program p .. integer :: i, j, k .. pcfs(i)%pcf => foo .. k = pcfs(i)%pcf(j) .. end program p
Note how the interface has been changed to refer to the invoking object via the "this" dummy argument. You may also know that by using the PASS attribute in the PROCEDURE statement in the derived type declaration, the developer can make the "this" argument to be second, third, or wherever appropriate on the dummy argument list; it doesn't have to be first. Also, the argument can be named "this", "self", "me", etc. - whatever naming convention is preferred.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Moreover, if I am trying to circumvent the problem by embedding the function pointer into a derived type as follows
module pcf_mod abstract interface function USERFUNC_int (arg) integer USERFUNC_int integer, intent(IN) :: arg end function USERFUNC_int end interface type :: ARRPROCPOINTER procedure(USERFUNC_int), pointer :: pcf end type ARRPROCPOINTER type(ARRPROCPOINTER) :: pcfs(100) end module pcf_mod
I am getting a totally unrelated compiler error:
error #8262: The passed-object dummy argument must be dummy data object with the same declared type as the type being defined. [ARG]
function USERFUNC_int (arg)
Removing the type related lines it compiles fine. It seems that I am stuck.
Rak
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As you found out, you have to use a derived type here. Fortran doesn't have the notion of an array of pointers.
The new error is simply a compiler bug. For some reason it thinks you're declaring a type-bound procedure, which you aren't. That's just weird - I will report it to the developers.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
The new error is simply a compiler bug. For some reason it thinks you're declaring a type-bound procedure, which you aren't. That's just weird - I will report it to the developers.
Steve, according to Fortran 95/2003 by M,R,C this is correct behavior:
When a procedure pointer component (or a type-bound procedure, Section 16.6) is invoked the object through which it is invoked is normally passed to the procedure as its first actual argument and the items in the parenthesized list are the other actual arguments. This could be undesirable; for instance, it might be wished to pass the object to a dummy argument other than the first or not to pass it at all.
Therefore, I don't think this is a compiler bug. For the OP to get the intended behavior, simply add the nopass attribute to the procedure pointer declaration in the derived type:
type :: ARRPROCPOINTER procedure(USERFUNC_int), pointer, nopass :: pcf end type ARRPROCPOINTER
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, I'll be darned. I'm always learning something new about this language.... Indeed you are correct, Zaak.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yeah, how they arrived at some of the finer points of the syntax for procedure pointer components really seems non-intuitive to me.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Zaak,
Assuming the nopass technique corrects the compiler complaint of compliance to the standard...
And assume the user wishes to pass the "this" pointer...
Could the user then explicitly declare the "this" pointer in the function interface?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
Zaak,
Assuming the nopass technique corrects the compiler complaint of compliance to the standard...
And assume the user wishes to pass the "this" pointer...
Could the user then explicitly declare the "this" pointer in the function interface?Jim Dempsey
Jim,
I'm not sure what you mean by the "this" pointer. If the user did want to pass the object as an actual argument to type bound procedure (TBP) or procedure being pointed to by the procedure pointer component, then the canonical way of doing this is to specify the first dummy argument of the procedure as being type-compatible with the encompassing "this" object and without adding any pass or nopass attributes to the component specification. If the procedure had only this one dummy argument, then when it is invoked via the TBP or procedure-pointer component, the encompassing object is implicitly passed as the first actual argument, and the user can invoke the procedure with no (explicit) actual arguments. e.g., obj%method(). If one were to give the TBP/procedure-pointer component the nopass attribute then the procedure could be invoked explicitly passing the object: obj%method(obj). These two scenarios are identical. In general I think explicit is better than implicit, but in this context it is reasonable to expect a procedure bound to an object to modify the objects state and appreciate the decrease in verbosity associated with this language feature.
So, if I correctly understand your question, the answer is 'yes.' At any rate, between this post and Fortran Fan's hopefully we've covered the ins and outs of the pass(_____) and nopass attribute, and objects implicitly or explicitly passed as actual arguments to their TBPs/procedure-pointer components.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
...
And assume the user wishes to pass the "this" pointer...
Could the user then explicitly declare the "this" pointer in the function interface?...
Jim,
Is the functionality shown in the code below what you're asking about? It is standard Fortran.
module pcf_mod type :: ARRPROCPOINTER procedure(USERFUNC_int), pointer, pass(this) :: pcf end type ARRPROCPOINTER abstract interface function USERFUNC_int (arg, this) import :: ARRPROCPOINTER integer USERFUNC_int integer, intent(IN) :: arg class(ARRPROCPOINTER) :: this end function USERFUNC_int end interface type(ARRPROCPOINTER) :: pcfs(100) end module pcf_mod program p .. integer :: i, j, k .. pcfs(i)%pcf => foo .. k = pcfs(i)%pcf(j) .. end program p
Note how the interface has been changed to refer to the invoking object via the "this" dummy argument. You may also know that by using the PASS attribute in the PROCEDURE statement in the derived type declaration, the developer can make the "this" argument to be second, third, or wherever appropriate on the dummy argument list; it doesn't have to be first. Also, the argument can be named "this", "self", "me", etc. - whatever naming convention is preferred.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Izaak Beekman wrote:
...
If one were to give the TBP/procedure-pointer component the nopass attribute then the procedure could be invoked explicitly passing the object: obj%method(obj). ...
In such a case, the invocation becomes analogous to that of a conventional Fortran subprogram: CALL method(obj,..) in the case of a subroutine and foo = method(obj,..) for a function.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Izaak Beekman wrote:
Yeah, how they arrived at some of the finer points of the syntax for procedure pointer components really seems non-intuitive to me.
Things start to make a little bit of sense to me when I consider what would be required for consistency with legacy FORTRAN. I assume that is what the Fortran 2003 standard writers had to contend with, trying to add new features while retaining syntax that, at a base level, is not alien to how it has been done since FORTRAN IV perhaps, or definitely FORTRAN 77. Considering all the constraints that any standards body would normally face and when one piles all the legacy stuff on top of it, I think Fortran 2003 creators did a remarkable job. But for many Fortran 2003 and 2008 features, I don't think I'll be writing any new code in Fortran!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you all for enlightening discussions on this subject. The code provided by FortranFan works like a charm. I have to admit that I would have never be able guess the correct syntax in this case, regardless of the modern FORTRAN bibliography worldwide available. The most puzzling for me is the presence of 'this' at lines 4, 8 and 12.
Rak
FortranFan wrote:
Quote:
jimdempseyatthecove wrote:...
And assume the user wishes to pass the "this" pointer...
Could the user then explicitly declare the "this" pointer in the function interface?...
Jim,
Is the functionality shown in the code below what you're asking about? It is standard Fortran.
module pcf_mod type :: ARRPROCPOINTER procedure(USERFUNC_int), pointer, pass(this) :: pcf end type ARRPROCPOINTER abstract interface function USERFUNC_int (arg, this) import :: ARRPROCPOINTER integer USERFUNC_int integer, intent(IN) :: arg class(ARRPROCPOINTER) :: this end function USERFUNC_int end interface type(ARRPROCPOINTER) :: pcfs(100) end module pcf_mod program p .. integer :: i, j, k .. pcfs(i)%pcf => foo .. k = pcfs(i)%pcf(j) .. end program p
Note how the interface has been changed to refer to the invoking object via the "this" dummy argument. You may also know that by using the PASS attribute in the PROCEDURE statement in the derived type declaration, the developer can make the "this" argument to be second, third, or wherever appropriate on the dummy argument list; it doesn't have to be first. Also, the argument can be named "this", "self", "me", etc. - whatever naming convention is preferred.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Rak,
You can just use the code you posted in your second example, but change
type :: ARRPROCPOINTER procedure(USERFUNC_int), pointer :: pcf end type ARRPROCPOINTER
with this:
type :: ARRPROCPOINTER procedure(USERFUNC_int), pointer, nopass :: pcf end type ARRPROCPOINTER
Fortran Fan was answering Jim's question. You do not need the extraneous dummy argument 'this' just add the nopass attribute to the procedure pointer component in your original code from your second post, as I showed above. I highly recommend this route over adding the unused dummy argument.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Izaak, nopass does the job as well.
Rak
Izaak Beekman wrote:
Rak,
You can just use the code you posted in your second example, but change
type :: ARRPROCPOINTER procedure(USERFUNC_int), pointer :: pcf end type ARRPROCPOINTERwith this:
type :: ARRPROCPOINTER procedure(USERFUNC_int), pointer, nopass :: pcf end type ARRPROCPOINTERFortran Fan was answering Jim's question. You do not need the extraneous dummy argument 'this' just add the nopass attribute to the procedure pointer component in your original code from your second post, as I showed above. I highly recommend this route over adding the unused dummy argument.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page