[comp.lang.fortran] MS-FORTRAN bug in string concatenation

HUESTIS@MPLVAX.SRI.COM (David L. Huestis) (02/14/91)

Under Microsoft FORTRAN the following simple program

       character string*4/'abc'/
       string = '*'//string
       write(*,*)string
       end

produces the output '**bb' while LAHEY and VAX yield '*abc'

Microsoft FORTRAN takes no precautions against the source strings
overlapping the destination string.

dodson@convex.COM (Dave Dodson) (02/15/91)

In article <2PWGG2@MPLVAX.SRI.COM> HUESTIS@MPLVAX.SRI.COM (David L. Huestis) writes:
>Under Microsoft FORTRAN the following simple program
>
>       character string*4/'abc'/
>       string = '*'//string
>       write(*,*)string
>       end
>
>produces the output '**bb' while LAHEY and VAX yield '*abc'
>
>Microsoft FORTRAN takes no precautions against the source strings
>overlapping the destination string.

The above program is non-standard.  In a standard-conforming program, string
variables cannot appear on both the left- and right-hand side of an assignment
statement.  A Fortran compiler can do anything with a non-standard program,
including, but not restricted to, giving an error message, compiling and
giving some "reasonable" answer, or compiling and giving an unreasonable
answer.  Different implementations that compile and give some reasonable
result may choose different reasonable results.

----------------------------------------------------------------------

Dave Dodson		                             dodson@convex.COM
Convex Computer Corporation      Richardson, Texas      (214) 497-4234

gt4512c@prism.gatech.EDU (BRADBERRY,JOHN L) (02/15/91)

In article <2PWGG2@MPLVAX.SRI.COM> HUESTIS@MPLVAX.SRI.COM (David L. Huestis) writes:
>Under Microsoft FORTRAN the following simple program
>
>       character string*4/'abc'/
>       string = '*'//string
>       write(*,*)string
>       end
>
>produces the output '**bb' while LAHEY and VAX yield '*abc'
>
>Microsoft FORTRAN takes no precautions against the source strings
>overlapping the destination string.

Hmmmm...this looks like a problem related to another thread concerning
goto's used to branch directly into the middle of IF-THEN-ELSE blocks. The
'problem' is confusion over what a compiler SHOULD do with non-standard
or illegal code fragments!!! Rather than slam Microsoft FORTRAN for not
being 'clairvoyant' in this case, consider this as a need to understand
the proper use of the concatenation operator. The only restriction
FORTRAN places on such usage is that overlapping substrings CANNOT appear
on both sides of the same assignment statement...

-- 
John L. Bradberry        |Georgia Tech Research Inst|001100110011001100110011
Scientific Concepts Inc. |Microwaves and Antenna Lab|Int : gt4512c@prism
2359 Windy Hill Rd. 201-J|404 528-5325 (GTRI)       |GTRI:jbrad@msd.gatech.
Marietta, Ga. 30067      |404 438-4181 (SCI)        |'...is this thing on..?'   

rich@boreas.whoi.edu (02/16/91)

In article <1991Feb14.185049.3535@convex.com> dodson@convex.COM (Dave Dodson) writes:
>In article <2PWGG2@MPLVAX.SRI.COM> HUESTIS@MPLVAX.SRI.COM (David L. Huestis) writes:
>>Under Microsoft FORTRAN the following simple program
>>
>>       character string*4/'abc'/
>>       string = '*'//string
>>       write(*,*)string
>>       end
>>
>>produces the output '**bb' while LAHEY and VAX yield '*abc'
>
>The above program is non-standard.  In a standard-conforming program, string
>variables cannot appear on both the left- and right-hand side of an assignment
>statement. 

>Dave Dodson		                             dodson@convex.COM


This is interesting...according to my Vax-Fortran manual (which describes
how they implement fortran 77)

"the character assignment statement has the form

   v=e
   
 where
 
 v as a character variable, array element, or substring
 
 e is a character expression
 
 If the length of the character expression is greater than the length of the 
 character variable [...] then the character expression is truncated on the
 right.
 
 If the length of the character expression is less than the length of the 
 character variable [...] then the character expression is filled on the
 right with spaces.
 
(similar rules hold true for DATA statements).


Nowhere does it mention that this is not standard conforming. However, if
this is indeed the case, then is the statement

	string='*'//string(1:3)
	
also non-conforming?




--
Rich Pawlowicz ----------------- INTERNET: rich@boreas.whoi.edu
Woods Hole Oceanographic Institution
"Home of the 59-cent squid burger (cheese extra)"
--------------------------------------------------------------

silvert@cs.dal.ca (Bill Silvert) (02/17/91)

In article <1991Feb16.143646.3332@netnews.whoi.edu> rich@boreas.whoi.edu writes:
>This is interesting...according to my Vax-Fortran manual (which describes
>how they implement fortran 77)
>
>"the character assignment statement has the form ....
>
>Nowhere does it mention that this is not standard conforming. However, if
>this is indeed the case, then is the statement
>
>	string='*'//string(1:3)
>	
>also non-conforming?

It's the ANSI standard, not the DEC manual necessarily, that says that
it is non-standard.  The same characater positions cannot occur on both
sides, meaning that the vendors can do the assignment in any order they
see fit.  So your example is non-conforming.

>Rich Pawlowicz ----------------- INTERNET: rich@boreas.whoi.edu
>Woods Hole Oceanographic Institution
>"Home of the 59-cent squid burger (cheese extra)"

That's Loligo.  We offer Ilex for 39 cents, cheddar included.
-- 
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

scavo@cie.uoregon.edu (Tom Scavo) (02/17/91)

In article <22078@hydra.gatech.EDU> gt4512c@prism.gatech.EDU (BRADBERRY,JOHN L) writes:
>In article <2PWGG2@MPLVAX.SRI.COM> HUESTIS@MPLVAX.SRI.COM (David L. Huestis) writes:
>>Under Microsoft FORTRAN the following simple program
>>
>>       character string*4/'abc'/
>>       string = '*'//string
>>       write(*,*)string
>>       end
>>
>>produces the output '**bb' while LAHEY and VAX yield '*abc'
>
>...The only restriction
>FORTRAN places on such usage is that overlapping substrings CANNOT appear
>on both sides of the same assignment statement...

So how do I fix these nonstandard routines without having
to resort to local character variables (which would put an
unnecessary limit on the length of each argument)?

*     length() computes the effective length of its argument (minus 
*     trailing spaces); minLength() computes the length minus leading 
*     AND trailing spaces.

      SUBROUTINE center(st)
*        IMPLICIT NONE

         CHARACTER*(*) st

*        Local variables:
         INTEGER i, j, k, m, n

*        Functions:
         INTEGER minLength, length

         n = length(st)

         IF ( n .GT. 0 ) THEN

            k = LEN(st)
            m = minLength(st)

*           i is the # of leading spaces in the uncentered string.
*           j is the # of leading spaces in the centered string.

            i = n - m
            j = (k - m)/2

            IF ( i .NE. j ) THEN
               st(j+1:j+m) = st(i+1:n)
               IF ( i .LT. j) THEN
                  CALL blank(st(i+1:j))
               ELSE
                  CALL blank(st(j+m+1:n))
               END IF
            END IF

         END IF

         RETURN
      END


      SUBROUTINE leftJustify(st)
*        IMPLICIT NONE

         CHARACTER*(*) st

*        Local variables:
         INTEGER m, n

*        Functions:
         INTEGER minLength, length

         m = minLength(st)
         n = length(st)

         IF ( m .NE. n ) THEN

*           Shift the string n-m characters to the left.

            st = st(n-m+1:n)

         END IF

         RETURN
      END


-------------------------------------------------------------------
Tom Scavo
scavo@cie.uoregon.edu

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (02/19/91)

In article <1991Feb16.202213.10167@ariel.unm.edu>, scavo@cie.uoregon.edu (Tom Scavo) writes:
> So how do I fix these nonstandard routines without having
> to resort to local character variables (which would put an
> unnecessary limit on the length of each argument)?

C     CALL PREPND(STRVAR, STRVAL)
C     has the effect that the non-standard statement
C     STRVAR = STRVAL // STRVAR
C     would have had if the right hand side were evaluated
C     before changing any part of the left hand side.
C     This subroutine uses a fixed amount of storage.

      SUBROUTINE PREPND(A, B)
         CHARACTER A*(*), B*(*)
         INTEGER ALEN, BLEN, KEEP, I
         CHARACTER TEMP*1

         ALEN = LEN(A)
         BLEN = LEN(B)
         IF (BLEN .GE. ALEN) THEN
            A = B(1:ALEN)
         ELSE
            KEEP = ALEN-BLEN
            DO 10 I = 1, KEEP
               TEMP = A(KEEP+1-I:KEEP+1-I)
               A(ALEN+1-I:ALEN+1-I) = TEMP
 10         CONTINUE
            A(1:BLEN) = B(1:BLEN)           
         END IF
      END

-- 
Professional programming is paranoid programming