lilian@mips.COM (Lilian Leung) (05/26/90)
In article <149@snll-arpagw.UUCP>, dandy@snll-arpagw.UUCP (David Dandy) writes: > I ported a public domain Fortran code to my DECstation 3100, and received > an f77 compiler error associated with a WRITE statement. Eliminating all but > the essential code, the offending subroutine looks like > > SUBROUTINE SKTEST ( LOUT, LINE, ILEN ) > IMPLICIT DOUBLE PRECISION ( A-H, O-Z ), INTEGER ( I-N ) > CHARACTER LINE*(*) > WRITE (LOUT, '(A)') > 1 'Error in SKSNUM...'//LINE(:ILEN)//' not found...' > RETURN > END ... > > Whether or not this is a bug with the MIPS 2.1 compiler, I have to admit > that I don't know what the WRITE statement is supposed to be doing (even > afters reading Wagener's explanation). Does anyone know a work-around to > this problem? I need to get this working before MIPS releases their next > compiler version. Is this a bug, or is it not "standard F77"? Please > respond by e-mail if you know of a fix or a work-around. It's frustrating > to RTFM and still not be sure what's going on. The above is a documented restriction on MIPS and ANSI FORTRAN. In Mips's Part II: FORTRAN Language Reference manaul, page 3-8, it states that "Except in a character assignment statement, concatenation of an operand with an asterisk(*) as its length specification is not allowed unless the operand is the symbolic name of a constant." In ASNI X3.9-1978 FORTRAN, page 6-8, it says the same thing. We will input this as a request for enhancement to our FORTRAN compiler. Meanwhile, the workaround is to assign LINE(:ILEN) to a local character variable with constant length specified and use that variable in your write statement, like this: SUBROUTINE SKTEST ( LOUT, LINE, ILEN ) IMPLICIT DOUBLE PRECISION ( A-H, O-Z ), INTEGER ( I-N ) CHARACTER LINE*(*) CHARACTER*100 TEMP TEMP = LINE WRITE (LOUT, '(A)') 1 'Error in SKSNUM...'//TEMP(:ILEN)//' not found...' RETURN END -- UUCP: {ames,decwrl,prls,pyramid}!mips!lilian (or lilian@mips.com) DDD: 408-991-7848 Lilian Leung (or 408-720-1700, Ext. 848) USPS: MIPS Computer Systems, 930 Arques, Sunnyvale, CA 94086-3650
sjc@key.COM (Steve Correll) (05/28/90)
In article <149@snll-arpagw.UUCP>, dandy@snll-arpagw.UUCP (David Dandy) writes: > > SUBROUTINE SKTEST ( LOUT, LINE, ILEN ) > IMPLICIT DOUBLE PRECISION ( A-H, O-Z ), INTEGER ( I-N ) > CHARACTER LINE*(*) > WRITE (LOUT, '(A)') > 1 'Error in SKSNUM...'//LINE(:ILEN)//' not found...' > RETURN > END > > produces the following from the compiler: > Error on line 4 of sktest.f: impossible element in concatenation. > > I'm confused because > 1. "Fortran 77: Principles of Programming" by J. L. Wagener (pp. 323- > 325) discusses this as a valid Fortran77 statement. > 2. This code compiles without error using VAX/VMS F77 compilers, > UNICOS CFT77 compilers, and Sun release 4.0 f77 compilers. > (And probably others--these are the only three I tried.) > > Whether or not this is a bug with the MIPS 2.1 compiler, I have to admit > that I don't know what the WRITE statement is supposed to be doing (even > afters reading Wagener's explanation). Does anyone know a work-around... The program is telling the compiler to print 'Error in SKSNUM...', followed by the first ILEN characters of the string variable named "LINE", followed by ' not found...'. I believe the program is illegal because section 6.2.2 on page 6-8 of the ANSI X3.9-1978 "Fortran 77" standard says: Except in a character assignment statement (10.4), a character expression must not involve concatenation of an operand whose length specification is an asterisk in parentheses (8.4.2) unless the operand is the symbolic name of a constant. For good measure, section 15.5.3 on page 15-9 says: A character dummy argument whose length specification is an asterisk in parentheses must not appear as an operand for concatenation, except in a character assignment statement (10.4). This funny restriction is meant to relieve the compiler of the burden of allocating temporary storage dynamically (it needs a temporary place to copy the concatenated strings into, and 'ILEN' is not known at compilation time). Wagener might claim the use of the substring "(:ILEN)" makes his code legal, but I don't buy that, since "line", "line(:)", and "line(:len(line))" are supposed to be identical, and clearly those substrings don't make the compiler's task any different. Anyway, all is not lost. Try the following workaround, which is perfectly legal Fortran 77: write(lout, '(3a)') 'Error in SKSNUM', line(:ilen), 1 'not found...' If you really must concatenate the strings, you can do it legally by creating your own temporary, though you must anticipate the maximum length you will ever need: subroutine sktest(lout, line, ilen) character*(*) line, head, tail integer tmpsiz parameter (head='Error in SKSNUM...',tail=' not found...') parameter (tmpsiz=256) character temp*(tmpsiz) temp = head // line(:ilen) // tail write(lout, '(a)') temp(1:len(head)+ilen+len(tail)) end -- ...{sun,pyramid}!pacbell!key!sjc Steve Correll