In 1986 and 1997, I advocated for a form of procedure in Fortran that
has been called "updater" and "accessor". The syntax for reference to
it looks like a function, but it can appear in a variable-definition
context. An "accessor" would be a function/updater pair with a
definition that guarantees the syntax in variable-reference and
variable-definition contexts is the same.
To go with this, you'd like to have an object type for an integer
sequence, with a constructor that looks like a substring selector or
subscript triplet, so you wouldn't need to find all the colons in your
code and replace them with commas. Or something. Or vice versa.
These would solve your problem, but have been repeatedly rejected.
This isn't a radical new idea.
Douglas T. Ross wrote about this in 1969 in a chapter in a book entitled
"Software Engineering," for which J. T. Tou was editor. Geschke and
Mitchell wrote about it in 1975 in Volume 1 of IEEE Transactions on
Software Engineering.
Mesa and POP-2, and perhaps other languages, provided updaters. Univac
FORTRAN V had a crude form arising from statement functions, which were
actually macros. They were allowed to appear in variable-definition
contexts if their definitions (RHS) were allowed to appear in
variable-definition contexts.
On Thu, 2016-09-22 at 18:17 -0400, Vipul Parekh wrote:
> I'm working on some older code that involves EQUIVALENCE statements
> involving CHARACTER variables and CHARACTER arrays and I'm looking at
> options to replace such statements. What comes to my mind immediately
> is to use the facility that makes use of the C address of the
> variable. And I can't think of anything else which won't involve a
> bunch of changes in client code, a no-no.
>
>
> The older code specifies EQUIVALENCE and uses the CHARACTER variable
> and the array interchangeably as follows:
>
>
> -- begin code --
> module m
>
>
> implicit none
>
>
> integer, parameter :: n = 2
> integer, parameter :: l = 6
>
>
> character(len=n*l) :: s
> character(len=l) :: t(n)
>
>
> equivalence (s, t)
>
>
> end module m
>
>
> program p
>
>
> use m, only : s, t
>
>
> integer :: i
>
>
> ! Some sections of code define 's'
> s = "123456789012"
>
>
> ! Then perform operations involving 't'
> do i = 1, size(t)
> print *, t(i)
> end do
>
>
> ! Other sections of code define 't'
> t(1) = "Hello"
> t(2) = "World!"
>
>
> ! Then perform operations involving 's'
> print *, s
>
>
> stop
>
>
> end program p
> -- end code --
>
>
> Upon execution, the above leads to
> -- begin output --
> 123456
> 789012
> Hello World!
>
>
> -- end output --
>
>
> All I could think of to achieve the same functionality but which
> doesn't involve too many changes in client code was to employ a setter
> method that takes the C address of a character scalar variable and
> associate a Fortran rank-one character array with POINTER attribute
> with it, as shown below.
>
>
> -- begin code --
> module m
>
>
> use, intrinsic :: iso_c_binding, only : c_loc, c_f_pointer
>
>
> implicit none
>
>
> integer, parameter :: n = 2
> integer, parameter :: l = 6
>
>
> character(len=n*l), target :: s
> character(len=l), pointer :: t(:) => null()
>
>
> contains
>
>
> subroutine set_t()
>
>
> call c_f_pointer( c_loc(s), t, shape=[n] )
>
>
> return
>
>
> end subroutine set_t
>
>
> end module m
>
>
> program p
>
>
> use m, only : s, t, set_t
>
>
> integer :: i
>
>
> ! Consumer has to remember to invoke this
> call set_t()
>
>
> ! Some sections of code define 's'
> s = "123456789012"
>
>
> ! Then perform operations involving 't'
> do i = 1, size(t)
> print *, t(i)
> end do
>
>
> ! Other sections of code define 't'
> t(1) = "Hello"
> t(2) = "World!"
>
>
> ! Then perform operations involving 's'
> print *, s
>
>
> stop
>
>
> end program p
>
>
> -- end code --
>
>
> The above code 'works' ok with the toolsets and platforms of interest
> at present with the caveat (a big concern) that the 'consumer' handles
> the pointer 't' carefully and doesn't do other dangerous stuff with
> it.
>
>
> Can readers suggest other, better options?
>
>
> Thanks much,
> Vipul Parekh
>
>
>
>
>
>
>
>
>
>
|