[comp.lang.fortran] A Q of constants

tlynchmj@cc.curtin.edu.au (05/24/91)

I have a problem initializing a constant array, can someone tell
me how to do it.

I want an array of characters to be initialiized as constants at compile time
and it has to be ANSI standard, more specifically, it must compile under
VAX-VMS F77 with the /STANDARD option invoked.

I tried this...

      CHARACTER SYMS(6)
      PARAMETER (SYMS = 'abcdef')

which gave me a 'symbol to big for constant' or something like that error.
Then I tried this...

      CHARACTER SYMS(6)
      PARAMETER (SYMS(1) = 'a',
     +           SYMS(2) = 'b',

       blah blah

and it gave me an implied do error. I thought that the second should work
for sure. Any tips?

Huw

KENCB@SLACVM.SLAC.STANFORD.EDU (05/24/91)

In article <1991May24.111123.8396@cc.curtin.edu.au>, tlynchmj@cc.curtin.edu.au
says:
>I want an array of characters to be initialiized as constants at compile time
>and it has to be ANSI standard, more specifically, it must compile under
>VAX-VMS F77 with the /STANDARD option invoked.
>
>I tried this...
>
>      CHARACTER SYMS(6)
>      PARAMETER (SYMS = 'abcdef')
>
>which gave me a 'symbol to big for constant' or something like that error.
>Then I tried this...
>
>      CHARACTER SYMS(6)
>      PARAMETER (SYMS(1) = 'a',
>     +           SYMS(2) = 'b',
>

   The trouble is you're trying to define an ARRAY as a PARAMETER.  You
can't in Fortran 77 (though I greatly wish one could :-).  Here's a
simple test program that compiles under VAX Fortran with the /STANDARD
qualifier and gives you three alternatives for what it appears you
want to do (excuse the non-standard mixed-case source ;-)

--------------------------------------------------------------------------
      Program Test
      Character c0(6)
      Character*6 c1
      Character*6 c2
      Parameter  (c2 = 'abcdef')
      Data c1 /'abcdef'/
      Data c0 /'a','b','c','d','e','f'/
      Write (6,'(X,6A/X,A/X,A)') (c0(i),i=1,6),c1,c2
      Stop
      End
--------------------------------------------------------------------

   Only the PARAMETER form gives you "an array of constants", and it's
not strictly an array.  However the standard Fortran 77 character handling
allows indexing into character strings which is nearly the same, e.g.
use C2(3:3) instead of C2(3).

 -Ken

 Dr. Kenneth H. Fairfield        Internet: Fairfield@Tpc.Slac.Stanford.Edu
 SLAC, P.O.Box 4349, Bin 98      DECnet:   45047::FAIRFIELD (TPC::)
 Stanford, CA   94309            BITNET    Fairfield@SlacTpc
 "These opinions are worth what you paid for 'em...
         ...and they are mine, not SLAC's, Stanford's, nor the DOE's..."

maine@altair.dfrf.nasa.gov (Richard Maine) (05/24/91)

On 24 May 91 03:11:22 GMT, tlynchmj@cc.curtin.edu.au said:

tlynchmj> I have a problem initializing a constant array, can someone tell
tlynchmj> me how to do it.

tlynchmj> I want an array of characters to be initialiized as
tlynchmj> constants at compile time and it has to be ANSI standard,
tlynchmj> more specifically, it must compile under VAX-VMS F77 with
tlynchmj> the /STANDARD option invoked.

tlynchmj> I tried this...

tlynchmj>       CHARACTER SYMS(6)
tlynchmj>       PARAMETER (SYMS = 'abcdef')

Alas, the ANSI standard does not allow constant arrays.  This
omission is rectified in Fortran 90, but you are out of luck
looking for such in standard Fortran 77.  I'm not even sure how
common constant arrays are as vendor extensions.

Possible workarounds:

1. Use variables initialized with either data statements or
   executable code.  This is aesthetically unappealing (to me
   anyway), but it is the only workable choice for most cases
   where I find myself wanting constant arrays.

2. For the particular case of character arrays like the example
   you cite, you might be able to use a constant character string
   instead.  I can't really tell without seeing how you want to
   use it.  Character strings and character arrays share some
   simillar ideas, but there are important distinctions.  One
   minor, but possibly relevant distinction is that the standard
   does allow you to define a constant character string as in

     CHARACTER SYMS*6      (or alternatively, CHARACTER SYMS*(*))
     PARAMETER (SYMS = 'abcdef')

  Unfortunately, ANSI Fortran 77 does not allow substrings of
  constant strings (another omission rectified in F90), which may
  make things awkward, depending on how you want to use SYMS.

3. Nag DEC to get out an F90 compiler soon.

--
--
Richard Maine
maine@altair.dfrf.nasa.gov

maine@altair.dfrf.nasa.gov (Richard Maine) (05/25/91)

On 24 May 91 05:36:54 GMT, KENCB@SLACVM.SLAC.STANFORD.EDU said:

        ... [reasonable discussion of how to approximate
             the effect of an array of constant characters in F77]

KENCB> Only the PARAMETER form gives you "an array of constants", and
KENCB> it's not strictly an array.  However the standard Fortran 77
KENCB> character handling allows indexing into character strings which
KENCB> is nearly the same, e.g.  use C2(3:3) instead of C2(3).

Unfortunately standard F77 does not allow such substrings of parameters.
I've been caught by this quirk myself.  Though it certainly looks
consistent and like it "ought" to be legal, it isn't standard.
Some compilers might accept it as an obvious extension, but I'm sure
that not all do.

See section 5.7.1 of the F77 standard, where substrings are defined
only for character variables or character array elements.  Constants
are not allowed, either as literals or by symbolic name.

As I mentioned in my other post, this is legal in F90.

It is possible to do roundabout things like

     character c1*6, c2*6
     parameter (c2='abcdef')
     ...
     c1 = c2
     whatever = c1(3:3)

though it will probably puzzle anyone reading the code why this
isn't expressed in the "obvious" (but illegal) way.

--
--
Richard Maine
maine@altair.dfrf.nasa.gov