|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Mon Jan 02, 2012 6:52 pm Post subject: Run time check for modification of agument expression |
|
|
Checkmate (/CHECK and /CHECKMATE) should generate a run time error when an attempt is made to modify a dummy argument when the corresponding actual argument is an expression.
I find this does not work for module procedures, but does work for external procedures. In the following code, suba is inside a module, subb is an external procedure. No runtime error occurs when suba is called, but the correct error occurs when subb is called.
Moreover, I have found that the following calls, which also have simple expressions for arguments (being parenthesised variables) are not detected at all!
call suba((k))
call subb((k))
Perhaps these inconsistencies could be addressed in some future revision.
I'm still using 6.10 here.
Code: |
module foo
contains
subroutine suba(i)
print *, i
i = 6 !< Should get a run-time error here. But I don't!
end subroutine suba
end module foo
!********************************
subroutine subb(i)
print *, i
i = 6 !< Should get a run-time error here. And I do!
end subroutine subb
!********************************
program anon
use foo
integer :: k
k = 5
call suba(k*10)
print *, k
k = 5
call subb(k*10)
print *, k
end program anon
|
_________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Tue Jan 03, 2012 12:25 pm Post subject: |
|
|
I have made a note of this for further investigation. |
|
Back to top |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Wed Jan 04, 2012 8:07 am Post subject: |
|
|
Thanks for looking at this.
This problem also arises in the following "code 1".
The argument a is changed on exit from subroutine bar even though it has the INTENT(IN) attribute! No run time error occurs and a has the value 2.0 on exit from bar.
Code: |
! Code 1
module foo
contains
subroutine bar(a)
real, intent(in) :: a
call mar(a)
end subroutine bar
subroutine mar(a)
real :: a
a = 2.0
end subroutine mar
end module foo
program anon
use foo
real :: a = 1.0
call bar(a)
print *, a !< Prints the value 2.0
end program anon
|
However, with the following "code 2" the correct run-time error (Error 14) occurs.
Code: |
! Code 2
module foo
contains
subroutine bar(a)
real, intent(in) :: a
call mar(a)
end subroutine bar
end module foo
subroutine mar(a)
real :: a
a = 2.0 !< Run time error occurs here as expected.
end subroutine mar
program anon
use foo
real :: a = 1.0
call bar(a)
print *, a
end program anon
|
_________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Last edited by davidb on Thu Feb 16, 2012 9:41 am; edited 2 times in total |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Wed Feb 15, 2012 6:10 pm Post subject: |
|
|
I have investigated the first problem and find that modules are explicitly excluded from this checking process.
If I allow modules to be checked then I get the right outcome for your sample program but then a significant number of programs in our test suite fail.
It looks like a major task to put everything "right" so the best I can do is offer a special command line option so that you can experimentally bypass this exclusion. Evidently our test suite demonstrates that the result may be unsafe in ways that I cannot predict. |
|
Back to top |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Thu Feb 16, 2012 8:25 am Post subject: |
|
|
Thank you for investigating Paul. It is most appreciated.
For module procedures, I always use INTENT(IN) which detects this kind of error at compile time. However, the additional assurance of a run-rime check would be useful for codes where INTENT(IN) is not used, or where the module procedure calls another module procedure which does not use INTENT(IN), as in my second example (code 1) above.
It is difficult to see how enabling this run time checking for module procedures would break your test suite unless some of the code in the test suite is not valid. But, of course, this might be the case, and you may not want to make changes to the test suite if the work required is considerable.
However, the errors that such run-time checks can expose may be just the sort of things that it would be useful to expose in your customers fortran codes, especially for codes that contain a mix of module and non-module procedures. Certainly, there can be no valid codes which make changes to constant arguments since this is expressly forbidden by the Fortran Standard, so the inclusion of such checks cannot cause issues on correct code.
Would it be possible to enable this run time check for module procedures when /CHECK is used and simply compile your test suite with the /SUPPRESS_ARG_CHECK option specified?. This would be a much neater solution than an additional command line argument. Customers could use /SUPPRESS_ARG_CHECK if the use of /CHECK "breaks" their codes.
If this is not possible then an additional command line argument should be implemented (something like /CONST_ARG_CHECK ?).
David. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7928 Location: Salford, UK
|
Posted: Mon Feb 20, 2012 4:25 pm Post subject: |
|
|
I have revisited this issue and relaxed this limitation when using /check.
This means that (in the next release) your initial program above will now fault as expected.
The runtime checking process is not clever enough to handle every type of call to a module subprogram. This are apparent in our test suite in code that is valid but produces a false runtime checking error. Hence the need to relax the limitation rather than remove it altogether.
I am trusting that this change will enhance the checking features but there is an attendant risk of breaking some valid code when /check is used. However, /check should never be used to create executables/dlls for release so this will only impact code under development. If anyone encounters any adverse effects from this change then they can use /check with /inhibit_check 15 in order to revert to the former state of affairs. But remember this will not apply until the next release. |
|
Back to top |
|
|
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sat Jun 23, 2012 10:20 am Post subject: |
|
|
These run-time checks are working fine now in version 6.30 with all my tests.
Thanks. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
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
|