Назначение указателя переменной, где целью является только манекен

Чтобы избежать проблемы XY, я сначала подытожу свою общую цель.

У нас есть большая унаследованная кодовая база кода fortran77, в которой реализовано собственное распределение памяти. Он состоит из одномерного массива Work, эквивалентного для использования с различными типами. Это выглядит примерно так:

      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)

Затем пользовательский распределитель вернет индексы в этом рабочем массиве. У нас более удобные ассигнования для нового кода, но большая часть по-прежнему использует этот устаревший код.

Один из очевидных недостатков заключается в том, что все представляет собой одномерный массив, и программисту приходится вручную выполнять арифметические операции с указателями для индексации многомерных массивов. По этой причине было бы здорово переинтерпретировать части этого массива как n-мерные массивы с использованием указателей. К сожалению, нельзя добавить атрибут target к эквивалентным переменным.

Играясь, я создал этот минимальный пример, который решает наши проблемы без необходимости использования 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

С другой стороны

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

не компилируется, потому что target требуется для vec.

Итак, теперь мой вопрос:

  1. В моем минимальном примере скрывается неопределенное поведение? Я не понимаю, почему первый пример должен работать правильно, если второй нет.
  2. Как правильно преобразовать массив 1D Work без копии?

person mcocdawc    schedule 26.07.2020    source источник
comment
Я не могу сделать эквивалентную переменную целью, поэтому я не могу использовать этот способ переназначения границ указателя. В противном случае это был бы мой второй пример.   -  person mcocdawc    schedule 26.07.2020
comment
Если у объекта нет атрибута target, он не может быть целью указателя; если не использовать манипулирование указателем, то «переделка» может иметь другие формы в ответах на связанный вопрос. Если ни один не подходит, то вы смотрите на копии.   -  person francescalus    schedule 26.07.2020