To avoid an XY-problem I will first summarize my overall goal.
We have a large legacy codebase of fortran77 code, that implemented their own memory allocation.
It consists of a 1D Work
Array that is equivalenced to be used with different types.
It looks roughly like this:
Real*8 Work(1:IWORKLEN)
Real*4 sWork(1:IWORKLEN)
Integer iWork(1:IWORKLEN)
Character*1 cWork(1:2*ICWORKLEN)
Equivalence (Work,sWork)
Equivalence (Work,iWork)
Equivalence (Work,cWork)
The custom allocator will then return indices in this work array. We have nicer allocations for new code, but a large part still uses this legacy code.
One of the obvious drawbacks is that everything is a 1D array and the programmer has to do the manual pointer arithmetic to index multidimensional arrays.
For this reason it would be great to reinterpret parts of this array as n-dimensional arrays using pointers.
Unfortunately one cannot add the target
attribute to equivalenced variables.
While playing around I created this minimal example, which solves our problems without the need for target
:
program test_dummy_target
implicit none(type, external)
integer, allocatable :: work(:)
integer, pointer :: M(:, :) => null()
work = [1, 2, 3, 4]
M => recast(work, 2, 2)
write(*, *) M(1, :)
write(*, *) M(2, :)
contains
function recast(vec, n, m) result(mat)
integer, target, intent(in) :: vec(:)
integer, intent(in) :: n, m
integer, pointer :: mat(:, :)
mat(1 : n, 1 : m) => vec(:)
end function
end program
On the other hand
program test_dummy_target
implicit none
integer, allocatable :: vec(:)
integer, pointer :: M(:, :) => null()
vec = [1, 2, 3, 4]
M(1 : 2, 1 : 2) => vec
write(*, *) M(1, :)
write(*, *) M(2, :)
end program
does not compile, because target
is required for vec
.
So now my question:
- Is there undefined behaviour lurking in my minimal example? I don't get why the first example should work properly, if the second one does not.
- How do I properly recast the 1D
Work
array without a copy?