replica nfl jerseysreplica nfl jerseyssoccer jerseyreplica nfl jerseys forums.silverfrost.com :: View topic - Argument in brackets is an expression
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 

Argument in brackets is an expression
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Wed Dec 05, 2012 8:49 am    Post subject: Argument in brackets is an expression Reply with quote

I found an inconsistency with /CHECKMATE and expressions as actual arguments. Smile

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
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Wed Dec 05, 2012 9:14 am    Post subject: Reply with quote

I have noted your request.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sun Jan 18, 2015 11:21 pm    Post subject: Reply with quote

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 Wink ) 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
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1899

PostPosted: Mon Jan 19, 2015 2:11 am    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Tue Jan 20, 2015 12:06 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1899

PostPosted: Tue Jan 20, 2015 5:20 pm    Post subject: Reply with quote

Paul, the issue reported at the beginning of this thread is still present in the 7.10 compiler.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Tue Jan 20, 2015 5:51 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Tue Jan 20, 2015 10:55 pm    Post subject: Reply with quote

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
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1899

PostPosted: Wed Jan 21, 2015 1:07 am    Post subject: Reply with quote

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
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Wed Jan 21, 2015 9:15 am    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Wed Jan 21, 2015 9:30 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sat Jan 24, 2015 5:36 pm    Post subject: Re: Reply with quote

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
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1899

PostPosted: Sat Jan 24, 2015 6:06 pm    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Mon Jan 26, 2015 8:40 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Mon Jan 26, 2015 9:07 pm    Post subject: Re: Reply with quote

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 Very Happy

Thanks Paul.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
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
Goto page 1, 2  Next
Page 1 of 2

 
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