 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
KL
Joined: 16 Nov 2009 Posts: 155
|
Posted: Sat Apr 02, 2011 10:34 am Post subject: Problems with INTENT |
|
|
I have problems in passing integer variables through several subroutines in a specific system of subroutines. The integer variables are part of a module, are defined and are used in several subroutines that use the module. The reason why these integer variables are passed through some subroutines as arguments is that this is an independent system of subroutines where I cannot use the module. The rules for the INTENT attribute are
INTENT(IN) The procedure must not change the argument.
INTENT(OUT) The argument is undefined on entry and may be given a value in the procedure.
INTENT(INOUT) The argument may be given a value in the procedure.
Metcalf et al. adds that a dummy argument with INTENT(IN) must not be redefined by the procedure or by being passed on as an actual argument to a procedure that redefines it. So the rules are pretty clear.
I have tried several variants: first without the INTENT attribute, then with other settings. Always an error is reported. Are there further rules for such a situation?
Two results:
If I set in the last subroutine to which the variables are passed
Code: |
Subroutine c ( � , istop)
Integer , Intent (out) :: istop
�.
Istop = 0
|
I get the error message
Error 15, Attempt to access undefined argument to routine.
If I set
Code: |
Subroutine c ( � , istop)
Integer , Intent (inout) :: istop
�.
Istop = 0
|
I get the message
Error 14, Attempt to alter an actual argument that is a constant, an expression, an INTENT(IN) argument, or a DO variable.
Of course, all settings of the INTENT attribute in the subroutines that passed the variables where set consistently and according to the rules.
Has anybody experienced a similar problem? Or is this programming already too complex and produces unwanted side-effects?
Thank you in advance for your help,
Klaus Lassmann |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Sat Apr 02, 2011 5:41 pm Post subject: |
|
|
Klaus,
Have you tried this with a simple example code? I had a go:
Code: | PROGRAM E
X = 5.0; I=2
WRITE(*,*) 'On entry', X, I
CALL A (X, I)
WRITE(*,*) 'On exit', X, I
END
SUBROUTINE A (D, J)
INTEGER, INTENT (INOUT) :: J
REAL, INTENT (INOUT) :: D
WRITE(*,*) 'On entry to A', D, J
CALL C (D, J)
WRITE(*,*) 'On exit from A', D, J
RETURN
END
SUBROUTINE C (D, J)
INTEGER, INTENT (INOUT) :: J
REAL, INTENT (INOUT) :: D
WRITE(*,*) 'On entry to C', D, J
D = 6.0; J = 3
WRITE(*,*) 'On exit from C', D, J
RETURN
END |
and no matter what I do with INTENT (i.e. I tried IN, OUT and INOUT in A) on the way through subroutine A, or indeed, setting INTENT to OUT in subroutine C, the argument passing seems to work. I was expecting something not to work, and therefore I would learn something, and I was surprised not to be able to generate the error message!
Have you tried taking out the INTENTs - does that work?
If not, then my guess (and it is no more than a guess) is that somewhere along the line you (or your MODULE) change the number and/or type of the arguments, or that the MODULE is mangling something.
Eddie |
|
Back to top |
|
 |
KL
Joined: 16 Nov 2009 Posts: 155
|
Posted: Sun Apr 03, 2011 4:59 pm Post subject: |
|
|
Dear Litus,
thank you very much for your quick reply. Of course I have checked everything carefully not only for hours but for days. But you certainly know that once you have overlooked something it is difficult to find. I�ll try tomorrow again.
One thing puzzles me: In the development phase I normally compile my program with the options /checkmate /Full_Debug. With these options I get the reported error messages. If I run the program without these options, the (rather big) program runs fine.
I have tried to demonstrate this problem with a small code, but up to now I failed to exactly reproduce this error. However, with the following program I observe also a strange effect:
With the compiler options /checkmate /Full_Debug I get the error message
Code: |
Access violation
DRIVERABC
TEST67
|
whereas without both options the code runs correctly. Here is the code
Code: |
Module GlobalData
Integer :: nwrite, istop
End Module GlobalData
Program Test67
Use GlobalData
Implicit none
nwrite = 10
istop = 0
Open (Unit = nwrite, File = 'Test67.out' )
Call DriverABC
End Program Test67
Subroutine DriverABC
Use GlobalData
Implicit none
Call ABC (nwrite, istop)
End Subroutine DriverABC
Subroutine ABC (nwrite, istop)
Implicit none
Integer , Intent (in) :: nwrite
Integer , Intent (inout) :: istop
Call ABC_1
Contains
Subroutine ABC_1
Implicit none
Call ABC_2 (nwrite, istop)
End Subroutine ABC_1
End Subroutine ABC
Subroutine ABC_2 (nwrite, istop)
Implicit none
Integer , Intent (in) :: nwrite
Integer , Intent (inout) :: istop
istop = 1
write ( nwrite, * ) 'istop = ', istop
End Subroutine ABC_2
|
Best regards,
Klaus |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sun Apr 03, 2011 10:37 pm Post subject: |
|
|
I have encountered problems using internal subroutines that access a subroutines arguments by host association. This may be the cause of the problem. I don't have a simple example right now though, but if I get time I will post one.
It is not clear to me whether the subroutines that are outside the module (which have an implicit interface) are allowed to use INTENT without an explicit interface being created using an INTERFACE block. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8211 Location: Salford, UK
|
Posted: Mon Apr 04, 2011 12:48 pm Post subject: |
|
|
Klaus
I have had a look at the access violation produced by the program that you have posted above.
/check (and anything that implies /check) produces runtime checking of subprogram arguments (in addition to other checks both at compile time and at runtime). There are currently 14 types of checks and particular types can be inhibited with /inhibit_check n (where n is in the range from 1 to 14 inclusive).
The complexity of your code (though valid) has been too great for both type 5 and type 10 of the checking types which happen to be runtime checks on the arguments passed. In other words /check is very useful but apparently cannot handle the kind of complexity that you are aiming to use.
It is possible that we might be able to improve /check in order to handle this degree of complexity but in the meantime, when using /check with this code, you will also need to use
/inhibit_check 5 /inhibit_check 10
You will understand that /check provides additional tests during development. The fact that you miss out on a couple of these tests is not that important once you are happy that the arguments are being passed correctly. |
|
Back to top |
|
 |
KL
Joined: 16 Nov 2009 Posts: 155
|
Posted: Tue Apr 05, 2011 8:52 am Post subject: |
|
|
Paul,
I cannot see that such a structure is too complex. Just imagine a solver for a linear set of equations. This is exactly what is behind my example, namely a standard solver for a pentadiagonal system. Traditionally, we call inside a Fortran program 2 external subroutines: One is performing the decomposition and the other the rest. Inside these subroutines are exit conditions, sometimes just a stop. Fortran 95 with its possibility of having internal subroutines offers a much simpler structure. In my case of a pentadiagonal system the standard routine consists of a driver which calls the two external subroutines. Why not putting these 2 external subroutines as internal subroutines in the driver? The result is a single and well structured subroutine. Instead of 3 argument lists we get only one. Of course it must be possible to exit from an internal subroutine and pass some variables to an external subroutine which deals with the stop condition. By the way, this new formulation has been tested successfully by 1000000 random test cases in a specific test environment but fails in a larger code.
From this problems and from past experience I get the impression that the debugger has in few specific circumstances problems with the full range of Fortran 95 possibilities. Since we all know about the tremendous importance of the debugger within the development of large code systems, I would like to express my strong interest in any further development of the debugger.
Best regards,
Klaus |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8211 Location: Salford, UK
|
Posted: Tue Apr 05, 2011 9:18 am Post subject: |
|
|
I have not explained this situation very well. The Fortran code is good but the existing runtime checking provided by FTN95 and salflibc.dll is not clever enough to handle your code. The problem does not involve the debugger SDBG.
Runtime checking of arguments passed to subprograms is a non-trivial operation for a language like Fortran 95. The people who wrote FTN95 have had a good go at it but /check still cannot handle everything that the the Fortran standard allows. /check is a useful tool not normally provided by other compilers so in that sense it is a bonus and it works in most cases. When it does not work, you can switch it off locally or use /inhibit_check.
Having said all of this, I will try to fix this particular problem. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8211 Location: Salford, UK
|
Posted: Tue Apr 05, 2011 9:19 am Post subject: |
|
|
I have not explained this situation very well. The Fortran code is good but the existing runtime checking provided by FTN95 and salflibc.dll is not clever enough to handle your code. The problem does not involve the debugger SDBG.
Runtime checking of arguments passed to subprograms is a non-trivial operation for a language like Fortran 95. The people who wrote FTN95 have had a good go at it but /check still cannot handle everything that the the Fortran standard allows. /check is a useful tool not normally provided by other compilers so in that sense it is a bonus and it works in most cases. When it does not work, you can switch it off locally or use /inhibit_check.
Having said all of this, I will try to fix this particular problem. |
|
Back to top |
|
 |
KL
Joined: 16 Nov 2009 Posts: 155
|
Posted: Wed Apr 06, 2011 9:03 am Post subject: |
|
|
Thank you very much for your explanations, Paul. Indeed, I was not really aware of the difference between runtime checking and debugger. I agree with your arguments about runtime checking. However, the problem is that if you get an error message which clearly says that something is wrong, you look first in your code. In my case for days.
Since I am now aware of some shortcomings of the runtime check utility, I can of course live with it. Saying this I would nevertheless appreciate a review of the runtime checking tool, especially with view on misleading error messages.
Best regards,
Klaus |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8211 Location: Salford, UK
|
Posted: Tue Apr 12, 2011 8:19 am Post subject: |
|
|
I have fixed this bug for the next release. |
|
Back to top |
|
 |
KL
Joined: 16 Nov 2009 Posts: 155
|
Posted: Tue Apr 12, 2011 9:40 am Post subject: |
|
|
Paul,
thank you very much. Will this correction be part of FTN 6.10, which has not released yet?
Klaus |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8211 Location: Salford, UK
|
Posted: Tue Apr 12, 2011 10:18 am Post subject: |
|
|
No. 6.10 has already been released. |
|
Back to top |
|
 |
|
|
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
|