|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2593 Location: Sydney
|
Posted: Thu Jun 11, 2015 2:24 pm Post subject: |
|
|
Mecej4,
My thoughts were based on: Code: | integer function ifact(n)
integer n
ifact = n
do while(n > 1)
n = n-1
ifact=ifact*n
end do
return
end function
|
I have never liked do while, it sounds like it should skip invalid values, rather than exit.
John |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Thu Jun 11, 2015 2:39 pm Post subject: Re: |
|
|
JohnCampbell wrote: | Mecej4,
My thoughts were based on: Code: | integer function ifact(n)
integer n
ifact = n
do while(n > 1)
n = n-1
ifact=ifact*n
end do
return
end function
|
| OK, now I see that you made some changes to the code, thereby reducing the number of bugs in it. At any rate, Dan has his own ideas about how to fix the bugs in his code, so none of this matters as far as he is concerned.
Quote: | I have never liked "do while", it sounds like it should skip invalid values, rather than exit. | DO WHILE is defined in the Fortran standards. The DO WHILE construct is very similar to the "while(integer expression){}" of C.
For selectively operating on some but not all elements of a set or array, based on a condition or mask, "when" and "where" would be more appropriate. In fact, Fortran has the WHERE construct. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8036 Location: Salford, UK
|
Posted: Mon Jun 22, 2015 1:58 pm Post subject: |
|
|
This may be relevant to an earlier post that I saw on this thread.
/check implies /debug (i.e. /debug is part of /check),
/undef implies /check,
/full_undef implies /undef,
/checkmate is an alias for /full_undef.
Students of Fortran are usually advised to write IMPLICIT NONE at the head of every subprogram - it saves the student and the tutor a great deal of wasted time and effort. Experienced users will have their own preferences.
I would advise users of FTN95 to always use /checkmate when testing and developing their code. Finished code should be built without using any of the debugging options. |
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2876 Location: South Pole, Antarctica
|
Posted: Mon Jun 22, 2015 7:29 pm Post subject: |
|
|
Making long things short, in this code
Code: | parameter (leve1=10)
character*(level) chVar
chVar='Debug me'
Print*, chVar
end
|
either compiler or debugger or better both have to stop exactly on the offending line when compiler with /checkmate or /undef
/* John, Do you mean you have 8 browsers open or just 8 tabs? By the way, here are my current tabs, sans the Safari, Maxthon and one unnamed browser
Last edited by DanRRight on Mon Jun 22, 2015 8:49 pm; edited 1 time in total |
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2876 Location: South Pole, Antarctica
|
Posted: Sun Jul 12, 2015 11:35 am Post subject: |
|
|
As a bottom line, here is the question : is the subject of this post considered as a bug or feature at Silverfrost ? |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2593 Location: Sydney
|
Posted: Mon Jul 13, 2015 4:13 am Post subject: |
|
|
Dan,
I think that it is a compiler error, but you should use /implicit_none, which would more easily find this and other similar errors.
/implicit_none basically says that all used variable names should be in the dictionary of declared names. I find this a very useful approach when writing code, as each time I get an error I then check if the variable is misspelt or I have omitted the variable name from the dictionary.
I put the variable declarations in include files and also modules. I don�t use dimension statements.
Also, thanks for your code example as I have learned how to drop a file into a clearwin+ program. see my pm for details
John |
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2876 Location: South Pole, Antarctica
|
Posted: Tue Jul 14, 2015 2:20 am Post subject: |
|
|
John, implicit none makes annoying necessity to declare default i,j,k,l,m,n and anything started with them. If you still have large portion of codes written with old style, you will be mixing the styles which is invitation for the disaster. You expect variable to be real but it is declared as integer - you are in troubles, you may never find this error.
You do not know the type variable in implicit none and with large code it is terrible work to go and find that all the time.
As i mentioned above /undef has MUCH more value then implicit none - it checks your program logic whole code's further life when you make additions or changes, not just initial typos as with implicit none (i usually do a lot of typos, nobody in the world make more errors and typos then me, unfortunately for me English language is just a colorless abracadabra, i do not feel it and hardly memorize it, i type too slow, permanently change everything, but all the typos are at the beginning when i write the program, then, since my variables are long, i just copy/paste them). Typos is too small portion of all possible errors. And /UNDEF will find them anyway.
OK, imagine you opened some regular (with no implicit none) source where error is. Your long name variables tell you what they are for, integer and real types are more or less clear and you quickly find the error not jumping anywhere. With implicit none style you permanently jump up to the header to find what the heck is this or that variable and the number of such variables in the large code called **gazillion**
So, no, thanks. Implicit none is dead wrong approach with large codes if compiler has /undef. Yes, undef does not catch some rare errors. But it catches 1000 times more then implicit none. Other compilers are too slow with /undef, Lahey, for example, is 10x slower then this one, see Polyhedron |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2593 Location: Sydney
|
Posted: Tue Jul 14, 2015 3:50 am Post subject: |
|
|
Quote: | You expect variable to be real but it is declared as integer - you are in troubles |
Dan, it is YOU, the programmer who may declare what you expect to be real as integer, not implicit none. The only scare campaign you have should be directed at what you code.
Having a list of active variables helps me understand what I am doing. It also lets me stop and review the name of each new variable, so that it's name helps with the code. I still typically use i,j,k as integer do loop counters, (but I avoid "l" as most fonts make this difficult to differentiate from 1).
I rarely have a real variable starting with i:n, but do generalise for integer counters. All logicals and characters need a declaration.
Most of the code samples I have posted would probably adhere to the implicit type convention.
I have /implicit in ~\silverfrost\ftn95\ftn95.cfg so new code can be a challenge. I have to update all declarations, which I find a good thing.
Anyway, we'll both code the way we find best and perhaps choose other approaches from time to time.
At the moment I can't use /UNDEF, as I have trouble with any checking options; /check or stronger changes the way ALLOCATE works. I need something like /ALLOC_malloc to go with /CHECK.
John |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2393 Location: Yateley, Hants, UK
|
Posted: Tue Jul 14, 2015 3:21 pm Post subject: |
|
|
Logicals and characters may need explicit typing, but commonly they are the smallest part of a Fortran program. You forgot to mention COMPLEX. Since a logical has to be true or false, then it is in effect the answer to a question, and a useful extension to implicit typing is to set all logicals to begin with 'Q', or 'Query' or couch its name as a question. Even a LOGICAL*1 has 256 possible 'answers' so I consider them perhaps not to be LOGICAL as much as POLITICAL (and just imagine how may shades of grey you could have with a LOGICAL*8 ...
I note that Dan isn't a native English speaker, but I get what he means when he reads code and makes an assumption about its type from its initial letter, and how tedious it is scrolling up and down codes to check on the type of something if you do use IMPLICIT_NONE.
Eddie |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2593 Location: Sydney
|
Posted: Wed Jul 15, 2015 4:48 am Post subject: |
|
|
Eddie,
This is getting ridiculous !!
YOU the programmer chooses what to start integer or real variable names with.
All IMPLICIT NONE does is to make you list all variable names in declaration statements, so that you have a spell check for all variables being used.
A secondary benefit is that when you introduce new variables into code as you are writing and testing, that the error report says "this is a new variable name; is this what you want ?" You can then introduce it to the "dictionary" or choose a better name.
Try it; you may be surprised how helpful it is. Otherwise use your other methods of spell check.
John |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Wed Jul 15, 2015 2:06 pm Post subject: |
|
|
Quote: | (DanRRight, July 13, 2015) So, no, thanks. Implicit none is dead wrong approach with large codes if compiler has /undef. Yes, undef does not catch some rare errors. But it catches 1000 times more then implicit none. | Dan is entitled to use whatever methods he prefers, but the justifications that he listed are incorrect.
First of all, IMPLICIT NONE and /undef are not mutually exclusive. We can use one or both or none, as appropriate to the situation at hand. IMPLICIT NONE is just one ingredient of static code checking, whereas /undef is just one ingredient of dynamic code checking.
There is more to debugging than just catching misspelled variable names, whether at compile time or at run time. A program may contain, in addition to misspelled variable names, incorrect argument lists passed to subroutines and functions, etc. With such errors present, even with /undef causing the program to issue an error and abort, you will still have to diagnose why the variable became undefined.
Dynamic error checking, in general, and /undef, in particular, only covers those parts of the code that got executed in a particular run. Consider this code fragment
Code: |
if (iter > itmax) then
ierr = -1
call vperr (iprint, ierr, 1)
go to 95
endif
|
Most of the time, the iterative algorithm that this code implements converges without iter exceeding itmax. If all the test runs worked this way, the entire body of subroutine vperr would never have been tested, whether or not the programmer used /undef. A few years later, a customer tries this code on a tougher problem, vperr gets executed, and lots of mysterious errors surface. Who gets the pleasure of finding the bugs in that case? Who gets the blame?
Dan's refusal to use IMPLICIT NONE, even occasionally, reminded me of the reason stated by some automobile passengers do not wear seat belts -- that wearing them might hinder a quick escape after a crash. A couple of months ago, Nobel Laureate John Nash and his wife Alice died in a taxi-cab crash on their way home in New Jersey (USA) from the airport. The Nashes were returning from a trip to Norway, where John Nash had just been honored with the Abel prize in mathematics. Neither was wearing a seat belt, and both were ejected from the taxi after the crash. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2593 Location: Sydney
|
Posted: Thu Jul 16, 2015 3:35 am Post subject: |
|
|
Mecej4,
Your comment that /implicit is a static check, while /undef is a dynamic check is a useful interpretation.
Unfortunately, I rely on static checks, as at present I have problems with FTN95's /checking options that change the operation of ALLOCATE and stop my programs from working. /debug is about all that I can use.
John |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Thu Jul 16, 2015 3:54 am Post subject: Re: |
|
|
JohnCampbell wrote: | Mecej4,
Unfortunately, I rely on static checks, as at present I have problems with FTN95's /checking options that change the operation of ALLOCATE and stop my programs from working. /debug is about all that I can use.
|
John, I prefer static checks as well, since a single compilation run will flag all the errors that the compiler can detect in the source file; in some infrequent cases, the compiler cannot grok the code and may go haywire.
With /undef, on the other hand, you have to run the compile/link/test-run cycle for each error that is caught. For large programs, this can be slow. This is yet another reason why large programs (such as Dan's) cannot be debugged efficiently using only dynamic error checking.
As to the ALLOCATE bug, I urge you to create a reproducer (MWE) and submit it. We need to hunt these bugs down. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2593 Location: Sydney
|
Posted: Thu Jul 16, 2015 9:27 am Post subject: |
|
|
mecej4,
I have produced a reproducer, see:
http://forums.silverfrost.com/viewtopic.php?t=3071
A compilation option of /ALLOCATE:GlobalAlloc or /GlobalAlloc to go with /CHECK could change this, although I don't know of what other related issues this would cause.
I did not consider using GET_STORAGE@ instead of ALLOCATE, as I wanted to test the production code and thought this would require too many changes.
John |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Thu Jul 16, 2015 2:08 pm Post subject: |
|
|
Ah, now I see -- had you said something with "allocatable array arguments" I would have recognized the topic sooner. Rather than relying on nonstandard allocation routines or compiler options that control how allocation is done, I think that FTN95 should consider implementing TR-15581 (see ftp://ftp.nag.co.uk/sc22wg5/N1351-N1400/N1379.pdf ). This TR filled a long felt need in Fortran-95 without requiring full F2003 implementation. The case for adding the TR is stated well in the introduction of the TR by John Reid:
Quote: | There are many situations when programming in Fortran where it is necessary to allocate and deallocate arrays of variable size but the full power of pointer arrays is unnecessary and undesirable. In such situations the abilities of a pointer array to alias other arrays and to have non-unit (and variable at execution time) strides are unnecessary, and they are undesirable because this limits optimization, increases the complexity of the program, and increases the likelihood of memory leakage. The ALLOCATABLE attribute solves this problem but can currently only be used for locally stored arrays, a very significant limitation. The most pressing need is for this to be extended to array components; without allocatable array components it is overwhelmingly difficult to create opaque data types with a size that varies at runtime without serious performance penalties and memory leaks.
A major reason for extending the ALLOCATABLE attribute to include dummy arguments and function results is to avoid introducing further irregularities into the language. Furthermore, allocatable dummy arguments improve the ability to hide inessential details during problem decomposition by allowing the allocation and deallocation to occur in called subprograms, which is often the most natural position. Allocatable function results ease the task of creating array functions whose shape is not determined initially on function entry, without negatively mpacting performance.
|
|
|
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
|