From: fairfield@slacvx.slac.stanford.edu
Subject: Re: FORTRAN character strings (LONG)
Organization: Stanford Linear Accelerator Center
Date: Wed, 18 Nov 1992 18:49:32 GMT

    The following is a somewhat lengthy response to a question applicable
only to VAX FORTRAN.  If you're not interested, skip it now :-)

In article <1992Nov18.155753.20537@alw.nih.gov>, plugge@faxcsl.dcrt.nih.gov writes:
>	How gross is the following STRING structure.  I'd like to
>	develop some string functions are a structure.  Should I
>	stick with ASCIZ or a character string and length format
>	instead of the following -
>
>	Integer		Charlength
>	Parameter	(CharLength=132)
>
>	Structure	/String_Type/
>
>	  Union
>	    Map
>	      Character*(CharLength)	Char
>	    End Map
>	    Map
>	      Byte			Byte(CharLength)
>	    End Map
>	  End Union
>	  Integer			Length
>
>	End Structure

    The answer to your question depends entirely on your application. The
structure you've defined is perfectly fine if your application requires a
character buffer (Byte) argument as opposed to a character string descriptor
argument (Char).  For instance, I could imagine calling a FORTRAN 66 routine
that required a Hollerith argument rather than character (but see below).

    I presume you are aware (yes?) that VAX FORTRAN passes all arguments by
reference (pointer) _except_ character arguments.  The latter are passed by
_descriptors_, which are themselves structures.  (That is, the address of a
structure called a descriptor is passed, rather than the address of the
array of character bytes.)  For FORTRAN calls, I can't see any point in your
structure.

    For calls to C-language subroutines, you could use this structure
passing, e.g. SOME_STRING.BYTE as opposed to SOME_STRING.CHAR.  You could
also get away with passing just SOME_STRING since the address of the
structure is the same as the address of the Byte field.  On the other hand,
you can also use the %REF built-in to pass a character variable by reference
without resorting to your proposed structure.

    Given that you've constructed this structure, it looks as if you want to
retain the current occupied length of the string in the Length field.  If
you're going to that trouble, then the called routine has to know the
structure of SOME_STRING anyway, why don't you just use descriptors?  In
fact, a "more sensible" structure would omit the Byte field altogether:
the Char field retains in its descriptor the maximum length allowed (FORTRAN
character strings are static: you can't/shouldn't modify the length field
in the descriptor), while the Length field would keep the currently occupied
length of the Char field.

    I guess the last issue I hadn't mentioned was that FORTRAN always pads
character variables with blanks while other languages terminate the strings
with one or more null bytes (that's what you referred to above by ASCIZ).
System services seem to pad the full length of the input string with nulls.
C string routines simply terminate the string with a single null.  In the
former case, if the system service doesn't return a length (I'm thinking of
the RTL routine LIB$FIND_FILE), you can use STR$TRIM to return the non-
blank, non-null length.  For a string returned from C, you'd need to use
INDEX to find the first null (equivalence CHARACTER*1 NULL and BYTE BNULL;
initialize BNULL to 0; LENGTH=INDEX(SOME_STRING, NULL) - 1).

		Cheers, Ken
--
 Dr. Kenneth H. Fairfield    |  Internet: Fairfield@Slac.Stanford.Edu
 SLAC, P.O.Box 4349, MS 98   |  DECnet:   45537::FAIRFIELD (45537=SLACVX)
 Stanford, CA   94309        |  BITNET    Fairfield@Slacvx
 ----------------------------------------------------------------------------
 These opinions are mine, not SLAC's, Stanford's, nor the DOE's...
Newsgroups: comp.lang.fortran