forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Pointers and intent

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
simon



Joined: 05 Jul 2006
Posts: 122

PostPosted: Wed Feb 15, 2017 11:17 pm    Post subject: Pointers and intent Reply with quote

The following program creates a window with a menu item and a button, both of which call the same callback function, f, which is defined in module m. The call-back function allocates memory to two arrays, x and y, that are defined as pointers. It then tries to call a subroutine, s, which declares the arrays as Intent(Out) rather than as pointers (I think that is legal, but I am not certain), but only one of the arrays is actually assigned any values.

If you click on the menu item the program runs, but it hangs if you click on the button. FTN95 does not typically seem to complain if an Intent(Out) argument is left unassigned, and this problem only seems to occur if the callback function is activated from a window.

Any suggestions? I suppose the place to start is to confirm whether or not the coding is valid Fortran. Change the arguments in the subroutine to pointers and the problem disappears. However, if I make an equivalent change to my original 70,000 line program the problem is not resolved. And since it took me 3 working days to isolate the problem below, I'm hoping that diagnosing what might be happening with this small program will help fix my larger program!

Code:
Module m
!
  Real, Dimension(:), Pointer :: x => Null()
  Real, Dimension(:), Pointer :: y => Null()
!
Contains
!
 Function f()
  Integer :: f
!
  Allocate (x(2))
  Allocate (y(2))
  Print *, 'Call s2'
  Call s (x, y)
  Print *, 'Called S2'
  f = 2
  Return
 End Function f
!
!
 Subroutine s (x, y)
  Real, Dimension(:), Intent(Out) :: x, y
!
  Print *, 'Start'
  x(:) = 1.0
  Print *, 'End'
  Return
 End Subroutine s
End Module m
!
!
Winapp
Program cpt
!
  Use clrwin, Only: winio@
  Use m,      Only: f
!
  Integer :: ic_par ! - parent window control variable -
  Integer :: iw     ! - window argument -
  Integer :: ih_con ! - ClearWin+ window handle -
!
! Open test window
  iw = winio@('%ca@&', 'TEST')
  iw = winio@('%mn[test]&', f)
  iw = winio@('%cn%^5tt@%ff&', 'test', f)
  iw = winio@('%ff %`50.10cw&', 0, ih_con)
  iw = winio@('%lw', ic_par)
!
End Program cpt
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 122

PostPosted: Thu Feb 16, 2017 2:45 am    Post subject: Reply with quote

... I forgot to add that I have some reason for suspecting that the problem may only occur on Windows 10, but I'm unable to test that assertion.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 4536
Location: Salford, UK

PostPosted: Sat Feb 18, 2017 11:03 am    Post subject: Reply with quote

It looks like FTN95 is not able to pass x from f to s in this way.
It might be a programming error or a bug in FTN95.

It would be simpler to declare x (and y) as "allocatable" rather than as "pointer". This seems to work may be valid Fortran.

The fact that it "works" in 64 bit mode is interesting and may give a clue to what is going wrong.
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 122

PostPosted: Thu Feb 23, 2017 1:25 am    Post subject: Reply with quote

I agree it would be easier to declare x and y as allocatable rather than as pointers, but if x and y are allocated in s rather than in f, they can only be passed as arguments in Fortran 95 if they are pointers. I think at Fortran 2003 they can be passed as allocatable arguments, but FTN95 does not allow that. I would like to do something like the following, but it is not possible in FTN95. My Fortran 2008 compiler allows it.

Code:
Module m
!
  Real, Dimension(:), Allocatable :: x
  Real, Dimension(:), Allocatable :: y
!
Contains
!
 Subroutine s (x, y)
  Real, Dimension(:), Allocatable :: x, y
!
  Allocate (x(2))
  Allocate (y(2))
  Return
 End Subroutine s
End Module m
!
!
Program p
  Use m
!
  Call s(x, y)
  Print *, Allocated (x), Allocated (y)
End Program p
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 4536
Location: Salford, UK

PostPosted: Thu Feb 23, 2017 9:28 am    Post subject: Reply with quote

Thanks for this. It is on the list of things to investigate.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1660
Location: Sydney

PostPosted: Fri Feb 24, 2017 9:09 am    Post subject: Reply with quote

simon,

for your latest example, Silverfrost FTN95 does not support allocatable arguments, which is an F95 addition.
Try the following alternative, by referencing the allocatable arrays through the module. This is required for FTN95 to manage allocatable arrays, although F03 can do what you want, (without using modules)
( I actually don't understand the use of contains + the use of arguments that are already in scope. I may be missing some of your example )
Code:
Module m
 !
   Real, Dimension(:), Allocatable :: x
   Real, Dimension(:), Allocatable :: y
 !
 Contains
 !
  Subroutine s   ! remove arguments  (x, y)
!   Real, Dimension(:), Allocatable :: x, y
 !
   Allocate (x(2))
   Allocate (y(2))
   Return
  End Subroutine s
 End Module m
 !
 !
 Program p
   Use m
 !
   Call s   ! remove arguments  (x, y)
   Print *, Allocated (x), Allocated (y)
 End Program p
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 122

PostPosted: Fri Feb 24, 2017 11:53 pm    Post subject: Reply with quote

Thanks for the suggestion John. I've been considering that, but ideally I'd like s to be a generic routine, so that I can call it to assign memory to a variety of arrays - hence the preference to have them passed as arguments. Using pointers seems to be the only way to do that in Fortran95, but I was getting an unexpected error when running from ClearWin+, as my original posting indicates.

Regarding the Contains + routines with arguments that are declared in the module in the same, there were two considerations here:
1. Having the routine arguments allows arrays to be passed that were not originally from that module;
2. Having arguments allows the user to allocate a selection of the arrays.
I presented the example in this manner primarily to keep the example program as short as possible. But also, I suppose I prefer to avoid having routines that modify values that are not arguments (except perhaps for workspace) so that there are no unexpected changes; although that does sometimes make for long argument lists.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1660
Location: Sydney

PostPosted: Sat Feb 25, 2017 1:47 am    Post subject: Reply with quote

Quote:
Regarding the Contains + routines with arguments

I suspect I may be proved wrong, but I think this is a coding error. Subroutine S should not be contained.
You should use /xref to check what x and y you are using; the argument or the module arrays.

John
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group