- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can someone please comment.
I converted an older workspace in CVF to IVF. All compiles but when running I get unexpected behavior when calling a couple of subroutines. I have now spentdays debugging these two issues.
The first is: After second call to the function THERM it does not recognize data fa = -1.0. I later added the the FA=. Now it works. But why did it not work consistently before?
FUNCTION THERM (ID,ARG,FAOLD,DUMMYP)IMPLICIT DOUBLE PRECISION (A-H,O-Z) DATA FA/-1.D0/ X=ARG FA = -1.0
The second is:After the second call to sub flocal the variable n1 changes to 10. What is doing this and what else can I inspect to see why and fix it?
SUBROUTINE FLOCAL (IGET,SS,EROR,JCXCNT) IMPLICIT DOUBLE PRECISION (A-H,O-Z), INTEGER (I-N)As soon as the second call enters sub here, N1 changes to 10. The first call it was set to 1 seen below. The second pass imediately changes to 10 without being set by a variable.
DO 10 I=1,NTBL
IF(ITAB(I).EQ.6969)IBOATTAB=I10
CONTINUE IF (NPASS.LE.0) THEN XPASS=.FALSE. N1=KKINDS(1,1)Thanks for any help.
Ken
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ken,
I am not sure on your 1st question, but for the second question it would seem that you are expecting N1 to have been saved from the prior call to FLOCAL. To have persistance you need to declare N1 with the SAVE attribute (or compile with /Qsave to save all variables).
Your first question error may also be corrected with /Qsave.
Also, consider using in THERM
REAL(8), SAVE :: FA = -1.D0
And using in FLOCAL
INTEGER, SAVE :: N1 = (initial N1 to 0, -1, 9999, whatever)
Since your programhas problems of uninitialized variables (not saved), you may find it fruitful to compile and debug with the runtime check for uninitialized variables.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ken,
First, all of your "debug" configurations shouldhave all of the warnings set on, especially bounds checking. The problem with variable FA sounds suspiciously like an out of bounds overwite of memory somewhere.
The problem with N1 : If N1 is a local, unsaved variable of subroutine FLOCAL then it will be allocated storage automatically on entering FLOCAL, the contents of that storage will be whatever is in there at the time - there is no automatic initialisation of variables. If the first thing you do with N1 is an assignment to itthen the previous contents are immaterial.
hth
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Les/Jim, Very informative answers. I'll try that right now.
I also just used the locals view and see there is a N1STT equal to 10 that is comming from an include common block. But how could it be written to N1? There is no equivalence.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If N1 is truly independent of N1STT then it is just coincidence.
One of the problems of common blocks is out-of-bounds errors. An array in one common with some code "array(I) = something"where the value of I is out of the bounds of the array could overwrite data either in the same common block or in the next common block.
Most of us "older" programmers will have seen this before.
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve,
I did have success in getting it running with /Qsave and now to your recomendation I am looking for an interface error. /gen-interface and /warn came up with an error calling a charcter function with the *. But I am not that familiar with that call. Do you know what is the correct way?
Function below.
Ken
CHARACTER *(*) FUNCTION SHIFTBL(CHSTR)
CHARACTER *(*) CHSTRINTEGER I, JJ=1DO I=1,LEN(CHSTR)IF (CHSTR(I:I).EQ.' ') THENELSECHSTR(J:J) = CHSTR(I:I)CHSTR(I:I) = ' 'J = J + 1ENDIFENDDOSHIFTBL = CHSTRRETURNEND
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Functions returning CHARACTER*(*) are no longer standard Fortran and are considered bad practice, as the length depends on how you declare the function in the caller.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I always use
length=len_trim(string)
call sub(string,length)
Subroutine string (string,length)
integer length
character string(length)
...
...
and ALWAYS ensure thatI do not go beyond 'length'
when processing the string.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
function myfunc (arg) result (res)
character(len=*), intent(in) :: arg
character(len(arg)) :: res
This does require an explicit interface (putting it in a module will do it.)

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page