soccer jersey forums.silverfrost.com :: View topic - Request: Do full expression evaluation if /checkmate used
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 

Request: Do full expression evaluation if /checkmate used

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Suggestions
View previous topic :: View next topic  
Author Message
mecej4



Joined: 31 Oct 2006
Posts: 1896

PostPosted: Sun Dec 02, 2018 7:02 pm    Post subject: Request: Do full expression evaluation if /checkmate used Reply with quote

The suggestion/feature request grew out of an experience with a 20,000 line program (550 kbytes).

The NAG compiler was finding an undefined variable with this program, but FTN95 and Lahey found no such error. As usual, it took quite a bit of effort to find the explanation.

Here is a short example.
Code:
program undef
   implicit none
   integer :: i, ka, ix(3)
!
   call init(3,ix,ka)
   do i=1,3
      if(ka > 2 .and. ix(i) >= 0)then
         print *,'Found a case, i = ',i
      endif
   end do
end program

subroutine init(n,ia,k)
   implicit none
   integer k, n, ia(n)
   k=2
   ia(k) = 3
   return
end

The IF statement on the seventh line contains two expressions with an .AND. between them. The values of the variables in the expressions are such that the second part, IX(I) >= 0, need not be evaluated, but the compiler may decide to evaluate the second part. The programmer has to ensure that IX(I) is defined, and may expect the compiler to help with shortcomings when /checkmate or /undef has been specified.

Please consider the following change to the behavior of the checking code that is generated when /checkmate is specified. Ascertain whether all the expressions in the IF() have defined values, and issue the usual error messages if not. In other words, /checkmate or /undef would imply "No short-circuit evaluation". For the example code above, the programmer would find out with the compiler's help that IX(1) and IX(3) are undefined.

Thanks for your consideration.


Last edited by mecej4 on Mon Dec 03, 2018 2:55 am; edited 1 time in total
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1896

PostPosted: Mon Dec 03, 2018 2:58 am    Post subject: Re: Reply with quote

John-Silver wrote:
did the NAG compiler name specifically what variables were undefinied (i.e. the 2 you mention.

The error it gave is
Code:
Runtime Error: undef.f90, line 7: Reference to undefined variable IX(I)
Program terminated by fatal error
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Mon Dec 03, 2018 9:15 am    Post subject: Reply with quote

mecej4

Thank you for your feedback.

The Fortran standard does not specify that the first part of the logical condition must be evaluated before the second and I presume that the NAG compiler has used the reverse order in this context. You could test this by making both parts undefined.

If my presumption is correct then the NAG compiler is not doing more than FTN95.

Unfortunately it would be a significant task to get FTN95 to plant code to evaluate all the components of a logical AND (when earlier conditions fail).
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1896

PostPosted: Mon Dec 03, 2018 10:41 am    Post subject: Re: Reply with quote

PaulLaidler wrote:
... I presume that the NAG compiler has used the reverse order in this context. ... If my presumption is correct then the NAG compiler is not doing more than FTN95.

Paul, that is a good point, so I looked at the intermediate C code that the NAG compiler produces. Without -C=undefined, the relevant lines read
Code:
Tmp1 = 3;
INIT(&Tmp1,ix,&ka);
for(i = 1;i <= 3;i++) {
if (ix[i + -1]>=0 && ka>2) { ...<code to execute WRITE statement ...}

With -C=undefined, the code for the body of the DO is expanded to (I paraphrase)
Code:
If i is undefined, print message saying so.
If IX(I) is undefined, print message saying so.
If KA is undefined, print message saying so.
Tmp5 = ix[Tmp2]>=0 && ka>2;
If (Tmp5), execute WRITE statement

Thus, the checking is thorough. In particular, there is a check on the DO index I being defined during each iteration of the loop).

I also tried changing the order of the logical operands to
Code:
if(ix(i) >= 0 .and. ka > 2)then

and received the same "undefined IX(I)" as before, which is consistent with checking every variable that is present in the complete logical expression.

PaulLaidler wrote:
Unfortunately it would be a significant task to get FTN95 to plant code to evaluate all the components of a logical AND (when earlier conditions fail).

I understand completely, and I posted this thread to gauge the level of interest in being able to do such thorough checking.

Of course, the price of thorough checking at runtime -- the overhead -- is also large. The code in question, with the checks enabled, took 20X longer. On an i5-8400, the checked run took about 100 s. At the time that the code was written (1990s), the CPUs on PCs were not fast enough to make such runs feasible, so we can suspect that many old codes may still contain such bugs.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Mon Dec 03, 2018 11:05 am    Post subject: Reply with quote

mecej4

This confirms my presumption. The NAG compiler is evaluating the second expression before the first.

When trying to understand what is happening, it is not helpful to change the presented order of evaluation (in the code). What you need to do is to keep the same order but make both parts flag up "undefined" (by changing the code to access an undefined variable instead of ka at this point). Then you will get your original runtime failure, confirming that the second expression is evaluated first (at runtime).
Back to top
View user's profile Send private message AIM Address
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2393
Location: Yateley, Hants, UK

PostPosted: Mon Dec 03, 2018 12:31 pm    Post subject: Reply with quote

Just out of interest, how do you tell, just by looking at it, if an integer variable is undefined? Isn't it the case that all bit patterns in an integer variable represent valid integers? (Unlike a real, where a specific sequence indicates 'undefined').

Does the NAG compiler keep track of whether integer variables are, in fact, defined? Or does it allocate a special bit pattern to that effect?

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


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

PostPosted: Mon Dec 03, 2018 1:03 pm    Post subject: Reply with quote

The bit pattern for 32 bits is usually 0xF0F0F0.... which is a large negative integer. The chances of hitting it are small. It's more of a problem with INTEGER*1 and CHARACTER(1) variables.
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1896

PostPosted: Mon Dec 03, 2018 1:06 pm    Post subject: Reply with quote

FTN95 uses documented special values for representing 'undefined' integers of various kinds. There is a minute chance of an integer variable acquiring such a special value legitimately but end up being labelled as "undefined", but that is a price we have to accept.

I don't know the internal details of how NAG implements -C=undefined, but the C code segments that I have seen indicate that NAG generates and maintains tag variables, with various values signifying different status attributes.
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2393
Location: Yateley, Hants, UK

PostPosted: Mon Dec 03, 2018 2:26 pm    Post subject: Reply with quote

Aha! And so it is (documented). And how appropriate that it should be FOFO!

For a LOGICAL, anything except 0 and 1, I suppose.

Eddie
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1896

PostPosted: Mon Dec 03, 2018 3:33 pm    Post subject: Reply with quote

According to the online help, https://silverfrost.com/ftn95-help/devel/checking_for_undefined_variables_undef.aspx , and the FTN95.CHM file that I have in the FTN95 folder, the values used to represent 'undefined' are Z'80', Z'8080' and Z'8080808080' for 1, 2 and 4-byte integers. When one of these values is placed in a register, the high bit gets extended if necessary to fill out the register.

With older compilers, I have seen Z'BAADF00D' and Z'DEADBEEF' used for similar purposes. Many of the debuggers used in the early days of PCs were not symbolic, and viewing a memory dump in hex would make the undefined variables obvious if one happened to be on the lookout for these patterns. See https://en.wikipedia.org/wiki/Hexspeak .
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Mon Dec 03, 2018 4:26 pm    Post subject: Reply with quote

Ah yes. I should have looked it up. F0F0... is used for something else - perhaps a dangling pointer.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Suggestions 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