[comp.lang.fortran] concatenated strings

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]