Подпрограмма на Фортране не распознает тип

У меня есть следующий код

module oc_tree

    type star
        integer :: id
        real(8) :: v(3)=0, r(3)=0
    end type

    type node
        real(8) :: corners(3,2)
        type(node), dimension(:), pointer :: child_nodes
        type(node), pointer :: father
        type(star), allocatable :: stars_in(:)
        real(8) :: tot_mass, center_mass(3)
        integer :: id
    end type node


    contains

    subroutine head_node(n2,m, stars, node1)
        real(8), intent(IN) ::m
        integer, intent(IN) :: n2
        type(star), allocatable, dimension(:), intent(in) :: stars
        real(8), parameter :: parsec = 3.085677581d16, d = 6661d3*parsec
        integer :: i

        type(node), intent(OUT) :: node1

        procedure...

    end subroutine head_node

   recursive subroutine tree(m, node1)
        type(node), intent(inout), target :: node1
        integer :: i, n, j, last_id
        real(8) :: c(3,2), r1(3)
        type(node), pointer :: node

        node => node1


        call child_cubes(node)

        procedure...

        end  subroutine tree

        subroutine child_cubes(node)
            type(node), intent(inout), target :: node
            real(8) :: x_mid, y_mid, z_mid, c(3,2)
            integer :: i

         procedure

        end subroutine child_cubes



end module oc_tree

По какой-то причине в подпрограмме "child_cubes" компилятор говорит:

"/home/avner/Dropbox/final project/grav/main.f95|176|Ошибка: "узел" производного типа используется до его определения"

хотя в двух первых подпрограммах у него нет проблем. Я не понимаю разницы между двумя первыми подпрограммами и этой, есть идеи?


person אבנר יעקב    schedule 05.08.2018    source источник
comment
Лично я не совсем верю, что это сообщение об ошибке появилось из опубликованного кода. Я думаю, что требуется минимальный воспроизводимый пример.   -  person High Performance Mark    schedule 06.08.2018
comment
Одно очевидное различие между подпрограммами заключается в том, что первые две не имеют фиктивного аргумента, называемого тем же, что и требуемый тип.   -  person francescalus    schedule 06.08.2018


Ответы (1)


При попытке скомпилировать с помощью gfortran 4.8.5 компилятор выдает следующую информативную ошибку в строке 37

type(node), pointer :: node
                           1   2
Error: The type 'node' cannot be host associated at (1) because it is
       blocked by an incompatible object of the same name declared at (2)

в дополнение к ошибке в строке 49

type(node), intent(inout), target :: node
          1
 Error: Derived type 'node' at (1) is being used before it is defined

Таким образом, проблема в том, что как фиктивный аргумент subroutine child_cubes, так и внутренняя переменная указателя subroutine tree имеют то же имя (node), что и тип, и, таким образом, затеняют тип. Изменение этих имен на node2 или что-то еще решает эту проблему (на самом деле, компилятор Intel прекрасно справляется даже с внутренней переменной-указателем, имеющей то же имя, что и тип, если вы переименовываете фиктивную переменную subroutine child_cubes, так что какие подпрограммы вызывают проблемы, зависит от компилятора).

person Kai Guther    schedule 06.08.2018
comment
Правила для этого приведены в разделе 16.3.1 (Классы локальных идентификаторов) стандарта F2008: в его рамках локальный идентификатор одного класса не должен совпадать с другим локальным идентификатором того же класса, за исключением того, что общее имя может быть таким же, как имя процедуры, как описано в 12.4.3.4, или таким же, как имя производного типа (4.5.10). Локальный идентификатор одного класса может совпадать с локальным идентификатором другого класса. Именованные переменные и производные типы находятся в одном классе. - person Steve Lionel; 06.08.2018
comment
Я сообщил Intel о невозможности диагностировать ошибку в дереве, идентификатор проблемы 03510955. Я также заметил, что сообщение об ошибке Intel Fortran для child_cubes не очень полезно. - person Steve Lionel; 06.08.2018