In updating virtually any large legacy package the use of scalars as
arrays and passing arrays with rank mismatches arises. Even widely
distributed packages (BLAS, LAPACK, ODEPACK, …) assume this is OK; it
was defacto a Fortran feature; but was not standard. It now complicates
modernizing a lot of packages, at least if you want to include all the
code in modules.
Sometimes there is a straight-forward option. If passing a scalar as
an INTENT(IN) array, place the value in brackets and create a temporary
array. If there are not a bunch of permutations of the arguments required,
create a generic interface, or create an ISO_C_BINDING interface to
memcopy(3c) or otherwise use C interface features. If just a shape
problem pass the array sizes and use them to dimension the arrays,
circumventing array bounds checks, … but without going on too much
more it can get complicated and is error prone to correct.
So assuming the standard will not change this soon, and given the
limitations of assumed-rank and assumed-shape arrays, is there a simpler
way to port code like this so it can be placed in standard-conforming
modules with less effort?
There are instances where things are much simpler if one can change the
rank of an array (or scalar) when it is passed to a procedure, as was
so often done in older code. If you can determine it is INTENT(IN) and
the overhead of a (probable) temporary array is acceptable RESHAPE(3f)
and PACK(3f) can be used, along with scratch variables but that is often
not the case. Elemental procedures, generic procedures, TRANSFER, SELECT
RANK, assumed size, array element sequence association, scratch arrays
and functions to reshape variables, … none of them supplies a simple
generic solution that I have thought of.
I keep leaving the more complex routines in older code outside of modules
for very extended times (maybe forever?) because of the complexity
required just to get sequence association in a module and because that is
so common in old code with dozens of arguments on their procedures.
As an exercise, I made a subroutine that would copy elements from IN
to OUT until the end of one of them is hit (the equivalent of a simple
memcopy(3c)) for scalars and/or arrays up to nine dimensions and it
took me almost 100 lines if I required not using C interfaces and that
it must be able to be placed in a module.
Hopefully, I am missing something simple?