Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29605 Discussions

subroutine call using array subobject syntax

Todor_K_
Novice
2,319 Views

Consider this code

program proba
  implicit none
  interface
     subroutine thunk()
     end subroutine thunk
  end interface
  
  type funptr
     procedure(thunk),pointer , nopass :: f
  end type funptr

  type(funptr) :: farr(3)

  farr(1)%f=>a
  farr(2)%f=>b
  farr(3)%f=>c

  call farr%f()

  

contains
  subroutine a()
    print *, 'a'
  end subroutine a
  subroutine b()
    print *, 'b'
  end subroutine b
  subroutine c()
    print *, 'c'
  end subroutine c
  
  
     
end program proba

If I compile this code with ifort 15.0.0 20140723 , the program prints only "a". Now, I think I have found somewhere in Metcalfs book that it is possible to access subobjects in an array of derived objects collectively, something like arr%a, instead of looping over the arr: arr(i)%a. However, in the code above, I am calling a subobject function pointer, apparently collectively since the compiler did not complain. I never knew this was possible, but the result is even more baffling. I would have expected that such an "array call" would in turn call each of the subobject functions separately, but what it does is calling only the first subroutine -- subroutine a(). Subroutines b and c are never invoked. I have used this syntax construct by accident, omitting a looping index in calls to farr(i)%f(). It looks very weird to me and I wonder if it is maybe a compiler's bug not to report such invocation. Is this anyhow possible within the Fortran standard?

0 Kudos
6 Replies
FortranFan
Honored Contributor III
2,319 Views

My hunch is this is a bug in Intel Fortran compiler that doesn't catch the error on line #18 of your code.  My take on the Fortran 2008 standard documentation, especially sections 12.5 and 6.4.2 and constraint C618, is such a reference is disallowed.

0 Kudos
FortranFan
Honored Contributor III
2,319 Views

Todor K. wrote:

.. Now, I think I have found somewhere in Metcalfs book that it is possible to access subobjects in an array of derived objects collectively, something like arr%a, instead of looping over the arr: arr(i)%a. ..

And if anything, Modern Fortran Explained by Metcalf et al. says exactly the opposite in section 13.6.2 - not that they (as Dr Fortran would remind us) are the final authority, the standard is.

 

0 Kudos
Todor_K_
Novice
2,319 Views

FortranFan wrote:

Quote:

Todor K. wrote:

 

.. Now, I think I have found somewhere in Metcalfs book that it is possible to access subobjects in an array of derived objects collectively, something like arr%a, instead of looping over the arr: arr(i)%a. ..

 

 

And if anything, Modern Fortran Explained by Metcalf et al. says exactly the opposite in section 13.6.2 - not that they (as Dr Fortran would remind us) are the final authority, the standard is.

 

 

Really?

The code below works when compiled in gfortran 4.9.2

program blah
  implicit none
  type jacko
     integer :: a
  end type jacko

  type(jacko) :: jackoarr(10)
  integer i
  do i=1,10
     jackoarr(i)%a=i
  enddo

  print *, jackoarr%a
end program blah

 

As far as I remember, though, this syntax is very restricted and I would be very suprised to see that Fortran 2008 allows anything like the program which I pasted into the original message. Hey, but I'm all for Fortran becoming a LISP variant :)

0 Kudos
FortranFan
Honored Contributor III
2,319 Views

Todor K. wrote:

..

Really?

The code below works when compiled in gfortran 4.9.2 ..  As far as I remember, though, this syntax is very restricted and I would be very suprised to see that Fortran 2008 allows anything like the program which I pasted into the original message. Hey, but I'm all for Fortran becoming a LISP variant :)

What does the code you show in this case have to do with the code in the original post?  Also, is it possible for you to upgrade your gfortran version?  v4.9.2 is rather outdated, especially when it comes to features from Fortran 2003 and 2008 standard revisions.  You can retry your original code with v5.2 or 6.0 development version of gfortran and see how it rejects it.  Additionally, change the component attribute of component a in type jacko in your program blah to be a POINTER, add an allocate statement for jackoarr(i)%a in the DO loop, and now try the print statement on line #13 and see how it gets rejected.  You can then review the details for yourself and delve into the commonalities between dereferencing of derived type data components with POINTER attribute and procedure pointer components.

Separately, I don't think the relevant aspects here have changed between Fortran 2003 and 2008 or even 2015, so not sure what you are getting at with your Fortran 2008 comment.  And what does any of this have to do with LISP?

0 Kudos
Steven_L_Intel1
Employee
2,319 Views

I agree that C618 prohibits the original program. C1230 (If data-ref is an array, the referenced type-bound procedure shall have the PASS attribute) also blocks what is being attempted here. I will let the developers know.

0 Kudos
Todor_K_
Novice
2,319 Views

FortranFan wrote:

Quote:

Todor K. wrote:

 

..

Really?

The code below works when compiled in gfortran 4.9.2 ..  As far as I remember, though, this syntax is very restricted and I would be very suprised to see that Fortran 2008 allows anything like the program which I pasted into the original message. Hey, but I'm all for Fortran becoming a LISP variant :)

 

 

What does the code you show in this case have to do with the code in the original post?  Also, is it possible for you to upgrade your gfortran version?  v4.9.2 is rather outdated, especially when it comes to features from Fortran 2003 and 2008 standard revisions.  You can retry your original code with v5.2 or 6.0 development version of gfortran and see how it rejects it.  Additionally, change the component attribute of component a in type jacko in your program blah to be a POINTER, add an allocate statement for jackoarr(i)%a in the DO loop, and now try the print statement on line #13 and see how it gets rejected.  You can then review the details for yourself and delve into the commonalities between dereferencing of derived type data components with POINTER attribute and procedure pointer components.

Separately, I don't think the relevant aspects here have changed between Fortran 2003 and 2008 or even 2015, so not sure what you are getting at with your Fortran 2008 comment.  And what does any of this have to do with LISP?

You misunderstood the part of my original post you quoted. I stated that array-subobject referencing works under certain conditions. I also remarked that the original construct probably does not fit within the legal fortran framework (as confirmed by Lionel below)

0 Kudos
Reply