|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
mecej4
Joined: 31 Oct 2006 Posts: 1896
|
Posted: Sun Dec 02, 2018 7:02 pm Post subject: Request: Do full expression evaluation if /checkmate used |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1896
|
Posted: Mon Dec 03, 2018 2:58 am Post subject: Re: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8011 Location: Salford, UK
|
Posted: Mon Dec 03, 2018 9:15 am Post subject: |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1896
|
Posted: Mon Dec 03, 2018 10:41 am Post subject: Re: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8011 Location: Salford, UK
|
Posted: Mon Dec 03, 2018 11:05 am Post subject: |
|
|
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 |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2393 Location: Yateley, Hants, UK
|
Posted: Mon Dec 03, 2018 12:31 pm Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8011 Location: Salford, UK
|
Posted: Mon Dec 03, 2018 1:03 pm Post subject: |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1896
|
Posted: Mon Dec 03, 2018 1:06 pm Post subject: |
|
|
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 |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2393 Location: Yateley, Hants, UK
|
Posted: Mon Dec 03, 2018 2:26 pm Post subject: |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1896
|
Posted: Mon Dec 03, 2018 3:33 pm Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8011 Location: Salford, UK
|
Posted: Mon Dec 03, 2018 4:26 pm Post subject: |
|
|
Ah yes. I should have looked it up. F0F0... is used for something else - perhaps a dangling pointer. |
|
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
|