1

I'd like to define some length-two characters variables using DATA statements, concatenating two named constants referring to single characters, directly in the DATA statement.

Is it possible? If so, what is the correct syntax? Is there a better, concise way to do that?

Example

use m_ascii_chars              ! this defines ch_* stuff as single character named constants
...
character(2) :: pairs(100)
...
DATA pair(1) /   ch_plus // ch_verticalbar   /  ! would be the best one, but it does not work,
                                                ! given the meaning of the slash in the DATA
                                                ! statement

DATA pair(1) / ( ch_plus // ch_verticalbar ) /  ! does not work !!
DATA pair(1) / [ ch_plus // ch_verticalbar ] /  ! does not work !!


! This works, but it is rather verbose
DATA pair(1)(1:1) / ch_plus /
DATA pair(1)(2:2) / ch_verticalbar /
...

! Of course, this works too, but does not fit the requirements.
DATA pair(1) / '+|' /
francescalus
  • 30,576
  • 16
  • 61
  • 96
GMA
  • 11
  • 3
  • I highly suggest to stop using `DATA`, it is really obsolete. Please show a more complete example and explain what "does not work" actually means for you. Is there some error message or anything? – Vladimir F Героям слава Feb 02 '21 at 10:54
  • I know, actually DATA statement is not in my habits, and I'll be happy to avoid using it (as in the last part of my question). Yes, the compiler issues different error messages depending on the (wrong) syntax I use (not worth reporting them). I do not want to define a big initialization array, I'd like to define each element using named constants only. Let's say: ` integer, parameter :: PLUS_VERTICALBAR = 1 ... pair(PLUS_VERTICALBAR) = ch_plus // ch_verticalbar ... ` I might do that in an initialization procedure, but I'd like to do that a compile time *as using the DATA statament) – GMA Feb 02 '21 at 11:13
  • @francescalus yes, in the example I used DATA on the variable array pairs. Defining pairs as a parameter (using a different syntax) would be even better. – GMA Feb 02 '21 at 11:16

1 Answers1

1

Character concatenation cannot appear in a value for a data statement. For the purposes of the question, the value to initialize a variable must be a constant. '+' // '|' is a constant expression but not a constant. The statement

DATA pair(1) / '+|' /

as noted is fine, because '+|' is a (literal) constant. A named constant with that value can be used similarly, and in the initialization expression for a named constant character concatenation (of constants) can be used:

character(*), parameter :: plusbar = ch_plus//ch_verticalbar
data pair(1) / plusbar /

As also seen,

DATA pair(1)(1:1) / ch_plus /
DATA pair(1)(2:2) / ch_verticalbar /

works. Although verbose, this can be written (slightly) more concisely:

DATA pair(1)(1:1), pair(1)(2:2) / ch_plus, ch_verticalbar /

Your compiler may support an implied-do for the substring, but this is non-standard.

If you want to provide initial values in pieces then you are stuck with data statements and here cannot use string concatenation. However, if you are able to provide an expression for the whole array then you can use concatenation:

character(2) :: pair(100) = [ch_plus//ch_verticalbar, ...]

Such an expression may well be cumbersome, but you have access to various techniques for building up this array.


The difficulty with '+'//'|' isn't with a parsing conflict of // with / of the separator. Similar restrictions apply with other expressions, such as not being allowed to have

integer i
data i /1+2/

(and of course 3*2 in the value list means 2,2,2 not 6)

francescalus
  • 30,576
  • 16
  • 61
  • 96