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: 132

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: 132

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: 4621
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: 132

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: 4621
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: 1692
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: 132

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: 1692
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
simon



Joined: 05 Jul 2006
Posts: 132

PostPosted: Wed Mar 01, 2017 3:36 pm    Post subject: Reply with quote

I seem to have inadvertently introduced a separate issue with the subroutine taking arguments that are declared in the same module. My original concern was about an apparent problem with a pointer being given an intent, but not consistently causing the program to hang. If this problem is a result of an illegal use of intent on a pointer, than that would be good to know, but I will have to go back and look more carefully at my larger program, since changing the offending intents back to pointers has not solved the problem.

Meanwhile, to illustrate the problem without introducing confouding issues around subroutine arguments, if I put X and Y in a separate module, the following program still hangs if I click on browse, but not if I click on the menu item.

Code:
! This program hangs if the button is selected but not the menu item
Module m1
!
  Real, Dimension(:), Pointer :: x => Null()
  Real, Dimension(:), Pointer :: y => Null()
!
End Module m1
!
!
Module m2
!
Contains
!
 Function f()
  Use m1
  Integer :: f
!
  Allocate (x(2))
  Allocate (y(2))
  Print *, 'Call s'
  Call s (x, y)
  Print *, 'Called s'
  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 m2
!
!
Winapp
Program cpt
!
  Use clrwin, Only: winio@
  Use m2,     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
JohnCampbell



Joined: 16 Feb 2006
Posts: 1692
Location: Sydney

PostPosted: Thu Mar 02, 2017 12:48 am    Post subject: Reply with quote

Simon,

I compiled your latest example in Plato and it ran using either menu or button.
I am using FTN95 Ver 8.05.0
buildlog is:
FTN95.EXE "C:\temp\forum\simon2.f90" /NO_BANNER /VS7 /DELETE_OBJ_ON_ERROR /ERROR_NUMBERS /UNLIMITED_ERRORS /LINK /CHECKMATE

FTN95 /64 gave an error with the kind of ih_con, even when declaring integer(7) ih_con
This was eventually corrected with ftn95 ver 8.10.0

Your example does not hang with 8.xx

John
Code:
! This program hangs if the button is selected but not the menu item
 Module m1
 !
   Real, Dimension(:), Pointer :: x => Null()
   Real, Dimension(:), Pointer :: y => Null()
   integer :: num = 0
 !
 End Module m1
 !
 !
 Module m2
 !
 Contains
 !
  Function f()
   Use m1
   Integer :: f
 !
   num = num+1
   Allocate (x(20000000))
   Allocate (y(20000000))
   Print *, 'Call s', num
   Call s (x, y)
   Print *, 'Called s'
   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 m2
 !
 !
 Winapp
 Program cpt
 !
   Use clrwin, Only: winio@
   Use m2,     Only: f
 !
   Integer    :: iw     ! - window argument -
   Integer(7) :: ih_con ! - ClearWin+ window handle -
   Integer    :: ic_par ! - parent window control variable -
 !
 ! 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


You should run this example in task manager, clicking test multiple times, as it demonstrates the memory leakage problem with pointers, as X and Y are not deallocated. I much prefer Allocatable arrays.
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 132

PostPosted: Thu Mar 02, 2017 2:39 am    Post subject: Reply with quote

Hi John,

Are you running on Windows 10? It doesn;t work on Windows 10, neither does my larger program, but my larger program does run on earlier versions of Windows.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1692
Location: Sydney

PostPosted: Thu Mar 02, 2017 4:20 am    Post subject: Reply with quote

Simon,

Yes !! I did to the test on Windows 7. My 3 other PC's are Windows 10, so I shall do the test soon.

I don't know why I changed from Win 7. The list of Win 10 improvements is fairly short. It's newer; not much more !!

Back to your origan post : I don't have much experience of pointers, as I try to avoid them. I find allocatable arrays in modules to be much more robust. I also rarely use INTENT=as it has little practical benefit in my type of coding.

John
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1692
Location: Sydney

PostPosted: Fri Mar 03, 2017 12:32 am    Post subject: Reply with quote

Paul,

Has there been any investigation of the work required to implement TR_15581:1999 ?

It has three main types of allocatable attributes:
array components of structures,
dummy arrays, and
array function results

The inclusion of Allocatable arrays as Dummy Arguments has been a useful extension to F95 for managing allocatable arrays, as Simon has shown in this thread.

I am not aware of the work required for this extension, so would be interested in your comments.

John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Fri Mar 03, 2017 8:32 am    Post subject: Reply with quote

John

I don't know for sure but I doubt it. Perhaps this will come apparent when we come to investigate this issue.
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