 |
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: Wed Dec 05, 2012 8:49 am Post subject: Argument in brackets is an expression |
|
|
I found an inconsistency with /CHECKMATE and expressions as actual arguments.
In the following two codes the argument (i) is an expression since i is in brackets.
In the first code (where i is undefined before the call to zzz), FTN95 correctly deduces that (i) cannot be evaluated since i is undefined and gives a run-time error with /CHECKMATE turned on.
Code: |
module foo
contains
subroutine zzz(j)
integer :: j
j = 5
end subroutine
end module foo
program main
use foo
integer i ! Declare i but leave it undefined
call zzz((i)) ! Run time error generated here, since (i) is expression
print *, i
end program main
|
In the second code (where i is defined before the call to zzz) the assignment to j should generate a run time error with /CHECKMATE but doesn't. However, if I replace (i) with a different expression, e.g. i+0 an error is generated.
Code: |
module foo
contains
subroutine zzz(j)
integer :: j
j = 5 ! Should generate a run time error here, but doesn't
end subroutine
end module foo
program main
use foo
integer i ! Declare i
i = 0 ! Define i before call to zzz
call zzz((i))
print *, i
end program main
|
Is it possible for a dummy argument that is associated with a bracketed actual argument be treated as a variable which cannot be changed please. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Wed Dec 05, 2012 9:14 am Post subject: |
|
|
I have noted your request. |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sun Jan 18, 2015 11:21 pm Post subject: |
|
|
I am resurrecting an old thread here.
In this code, where subroutine zzz has an explicit interface and uses intent(out), what is the correct treatment from the following list
- A result of 0 (this is the answer it gives)
- A result of 1
- Compile error
It is clearly (to me anyway ) illegal code so I would have thought the third option.
I could understand if this was an extension and returned 1 (i.e. brackets are treated as superfluous and removed), but the subroutine returns 0.
Code: |
module mmm
contains
subroutine zzz(a)
real, intent(out) :: a
a = 1.0
end subroutine zzz
end module mmm
program main
use mmm
real :: a
a = 0.0
call zzz((a))
print *, a, ' <- Prints 0 but should this be 1 (or is this illegal code)?'
end program main
|
_________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
mecej4
Joined: 31 Oct 2006 Posts: 1899
|
Posted: Mon Jan 19, 2015 2:11 am Post subject: |
|
|
I agree with you that the code is illegal. An INTENT(OUT) argument must be definable. An expression is not definable, so an expression cannot be the actual argument corresponding to an INTENT(OUT) dummy argument. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Tue Jan 20, 2015 12:06 pm Post subject: |
|
|
This issue has now been fixed for the next release.
The compiler now reports an error condition for expressions whilst before it only complained when the argument was a constant value. |
|
Back to top |
|
 |
mecej4
Joined: 31 Oct 2006 Posts: 1899
|
Posted: Tue Jan 20, 2015 5:20 pm Post subject: |
|
|
Paul, the issue reported at the beginning of this thread is still present in the 7.10 compiler. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Tue Jan 20, 2015 5:51 pm Post subject: |
|
|
I had assumed that the two issues had the same cause and hence that both would be seen to be fixed in the next release. However it turns out that the first issue is still outstanding. |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Tue Jan 20, 2015 10:55 pm Post subject: |
|
|
Well I must admit to being a bit confused (again!).
As I understand it there are two issues:
(1) When an actual argument is a variable in brackets, the argument should be treated as an expression (I don't think the compiler vendor can do otherwise as an extension -- this is part of the Standard). In most cases compiling with /CHECKMATE will detect at run time any attempt to alter the value of an actual argument expression by assigning a value to the dummy argument. However in the special case of a bracket-variable-expression it doesn't work.
(2) When an explicit interface (e.g. through USE of a module) and intent(out) is used for the dummy argument, the compiler should be able to detect at compile time that it cannot pass a constant or expression as the actual argument. It should be able to do this regardless of whether /CHECKMATE is used or not. In the special case of a bracket-variable-expression it doesn't work.
These issues are similar but not the same. One is a limitation of the run time checking system, the other is a bug in the syntactical analysis of the compiler.
Run-time checking with /CHECKMATE happens even with an explicit interface since version 6.30 (see release notes). The run time checking may seem redundant in such cases but it allows the "constantness" of the variable to be checked if it is subsequently passed to an external subroutine/function without an explicit interface. Therefore for protection in all cases it is necessary that both (1) and (2) work.
It looks like Paul has fixed issue (2) but not issue (1). Perhaps you can confirm Paul ? _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
mecej4
Joined: 31 Oct 2006 Posts: 1899
|
Posted: Wed Jan 21, 2015 1:07 am Post subject: |
|
|
Quote: | It looks like Paul has fixed issue (2) but not issue (1). |
It is quite clear to me from what Paul wrote that, indeed, that is true.
We should perhaps not be too fussy about whether a certain error is detected at compile time or at run time, although the former is most often preferable. Here is an example, taken from a rather large program, in which an active DO index is passed to a subroutine where it gets changed. FTN95 does not detect the bug at compile time, even if an explicit interface is available.
Code: | program tst
implicit none
integer :: i,j,k
do i=10,20
j=2*i*i-3
call sub(i,j,k)
write(*,*)i,j,k
end do
contains
subroutine sub(i,j,k)
implicit none
integer,intent(in out) :: i
integer, intent(in) :: j
integer, intent(out) :: k
k=i+j
i=i+1 !<<<=== illegal
return
end subroutine sub
end program tst |
|
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Wed Jan 21, 2015 9:15 am Post subject: |
|
|
This is an interesting case.
FTN95 can catch such errors at run time if /CHECKMATE is used.
However, this is another case where widening the definition of what constitutes an actual argument expression would be helpful.
For now, changing the argument from i to i*1 allows the compiler to see it as an expression and issue an error.
I know that not all wrinkles in the compiler can always be patched but it is at least helpful to be aware of these shortcomings when programming. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Wed Jan 21, 2015 9:30 am Post subject: |
|
|
Going back to the original sample program on this thread where the INTENT is not specified and hence is unknown to the compiler, let me begin with a word of explanation for those reading this post who are less familiar with the details.
In the call to zzz, the argument is in brackets so the compiler treats this as an expression to be evaluated and stored as a temporary. The address of the temporary is passed to zzz where its value is changed. On return this value is "lost" and the value of i remains the same as before the call to zzz. If i is initially undefined (and /UNDEF is used) then there will be a run-time failure when i is printed. In other words, you get the value of i before the call.
Given that the later issue (where the INTENT is specified) has been fixed for the next release, as far as I understand it, that's the best the compiler can do. In order to flag an error it is necessary to specify the INTENT as OUT or INOUT. If the INTENT is unknown to the compiler then (at the point of call) it cannot assume that it is not INTENT(IN). |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sat Jan 24, 2015 5:36 pm Post subject: Re: |
|
|
PaulLaidler wrote: |
In the call to zzz, the argument is in brackets so the compiler treats this as an expression to be evaluated and stored as a temporary. The address of the temporary is passed to zzz where its value is changed. On return this value is "lost" and the value of i remains the same as before the call to zzz. |
Yes indeed Paul; this is a good summary. But can you explain why the treatment of the temporary is different for the two codes below?
The first code gives "*** Error 14, Attempt to alter actual argument that is a constant, an expression, or ...", whilst the second code does not.
The only difference is that the expression in one case is (a) and in the other is a+0.
Code: |
subroutine xxx(a)
real :: a
a = 1.0
end subroutine xxx
program main
real :: a
a = 0.0
! Argument is expression so address of temporary is passed
call xxx(a+0)
print *,'a = ', a, ' <-- should be zero'
end program main
|
Code: |
subroutine xxx(a)
real :: a
a = 1.0
end subroutine xxx
program main
real :: a
a = 0.0
! Argument is expression so address of temporary is passed
call xxx((a))
print *,'a = ', a, ' <-- should be zero'
end program main
|
_________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
mecej4
Joined: 31 Oct 2006 Posts: 1899
|
Posted: Sat Jan 24, 2015 6:06 pm Post subject: |
|
|
For both the test programs in the previous post, NAG Fortran says:
Quote: | Runtime Error: x1.f90, line 3: Dummy argument A is associated with an expression - cannot assign
Program terminated by fatal error | Note the line number where the error is detected. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Mon Jan 26, 2015 8:40 am Post subject: |
|
|
For me (i.e. using the pre-release version) there is no difference in the behaviour. So I think that you will find that there will be consistency here.
I am not sure why but this appears to be included in the current fix. |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Mon Jan 26, 2015 9:07 pm Post subject: Re: |
|
|
PaulLaidler wrote: | For me (i.e. using the pre-release version) there is no difference in the behaviour. |
When you fixed the issue with intent(out) you must have fixed this as well without knowing.
Ideally the consistent behaviour you talk about should be a run-time error for both codes
Thanks Paul. _________________ 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
|