silvert@cs.dal.ca (Bill Silvert) (05/31/90)
I just tracked down a bug that seems to arise only with MS Fortran (I'm using ver. 5.0). When passing a complicated string involving the concatenation of several substrings to a subroutine, all is OK the first time through, but on the second call the program crashes. I think the code is legal, although complex. No problems of this sort arise on the two Unix compilers I have tried. I solved the problem by setting a string variable to the complex string and then passing the string variable to the subroutine. No, the problem does not arise from assigning part of a string to itself. I avoided that common bug. -- William Silvert, Habitat Ecology Division, Bedford Inst. of Oceanography P. O. Box 1006, Dartmouth, Nova Scotia, CANADA B2Y 4A2. Tel. (902)426-1577 UUCP=..!{uunet|watmath}!dalcs!biomel!bill BITNET=bill%biomel%dalcs@dalac InterNet=bill%biomel@cs.dal.ca
maine@pioneer.arc.nasa.gov (Richard Edwin Maine D-OFA) (06/01/90)
My apologies if this gets out twice. Outgoing news from my usual system is broken, so I reposted this from a different one. Please note the address in my .sig for replies. Mail to me on the system I'm posting this from could sit a long time unnoticed. On 31 May 90 12:58:21 GMT, silvert@cs.dal.ca (Bill Silvert) said: Bill> I just tracked down a bug that seems to arise only with MS Fortran (I'm Bill> using ver. 5.0). When passing a complicated string involving the Bill> concatenation of several substrings to a subroutine, all is OK the Bill> first time through, but on the second call the program crashes. Bill> I think the code is legal, although complex. Bill> I solved the problem by setting a string variable to the complex string Bill> and then passing the string variable to the subroutine. Bill, Just a suggestion on one fairly subtle possibility. I can't tell if it is related to your problem or not, but I've been bitten by it before. It IS a problem that goes away if you use an intermediate variable as you described. It's an interesting enough issue to merit posting anyway. Remember that in an actual argument you cannot (legally) concatenate a variable declared as character*(*). For instance the following is illegal. subroutine errmsg(msg) character msg*(*) call writeit('drat: '//msg) return end This is one of the "quirks" stuck in Fortran 77 to avoid the necessity of run-time dynamic memory allocation. Most "normal" implementations of this code would involve assigning a scratch memory area for the concatenated string, but the size of that area is not known at compile time. On the other hand, the following is legal (well,.. other than my use of lower case and long names) subroutine errmsg(msg) character msg*(*) character ctemp*80 ctemp = 'drat: '//msg call writeit(ctemp) return end The rationale is that, even though the length of the concatenated string is unkown at compile time, the code never needs to evaluate the whole string; just the first 80 characters. Some (many?) compilers accept the illegal usage and just do the dynamic memory allocation. But not all compilers accept it, and there are some compilers that do not diagnose the error, but don't compile it correctly anyway. Grumble, grumble. On quickly reviewing the standard before posting this, I find myself a little unsure of whether the following is legal. subroutine errmsg(msg,n,m) character msg*(*) integer n,m call writeit('drat: '//msg(n:m)) return end It seems that, in the spirit of the intent of the standard, this should be illegal, but I'm not quite sure whether the exact wording of the standard precisely covers this or not. The relevant wording is (section 15.6.2.2) An actual argument in a subroutine reference must be one of the following: (1) An expression except a character expression involving concatenation of an operand whose length specification is an asterisk in parentheses ... Hmm. Does that include concatenation of substrings of things with such length specifications? I'm not 100% sure. But if I wanted the code to work, I wouldn't do it. Oh, yes, as I write this, it does occur to me that one other mistake could possibly cause symptoms like those you mentioned. If the subroutine ever tries to change the value of the relevant formal parameter, strange things could happen with the concatenated expression, but things should work fine with a scratch variable. From your (Bill) prior postings, I'm pretty ssure that you would know about this common class of problems so I doubt that is it, but we all can slip up even on stuff we know, so I figured it was worth the reminder - no insult intended. -- Richard Maine maine@elxsi.dfrf.nasa.gov [130.134.64.6]