Инициализировать массив параметров c -размер параметризованного производного типа в Фортране? - PullRequest
5 голосов
/ 25 мая 2020

Фортран позволяет параметризовать размер элементов производных типов. Однако там, где элементы фиксированного размера могут иметь значение по умолчанию, назначенное в объявлении типа, похоже, нет способа для параметризованных записей:

PROGRAM main
  IMPLICIT NONE

  TYPE data1
     INTEGER :: array(5) = 2   ! allowed
  END type data1

  TYPE data2(n)
     INTEGER, LEN :: n
     INTEGER :: array(n) = 2   ! incorrect: error #8737 with intel fortran 19,
  END type data2               !            ignored by gfortran 8.2.1

END PROGRAM main

Назначение значений по умолчанию удобно, поскольку это позволяет избежать повторение инициализации каждый раз при использовании типа, но для полей размером с параметри c это запрещено; Gfortran просто молча игнорирует значение по умолчанию, а Intel Fortran выдает ошибку

error #8737: For a default initialized component every type parameter and array bound
             must be a constant expression.   [ARRAY]

Есть ли какой-нибудь синтаксис, который все-таки позволил бы определить значение по умолчанию?

Ответы [ 3 ]

1 голос
/ 25 мая 2020

Для таких компонентов не может быть инициализации по умолчанию.

Как указано в сообщении об ошибке Intel Fortran, границы массива для компонента с выражением инициализации должны быть постоянными выражениями (это ограничение C762 Fortran 2018) . Параметр типа длины не может использоваться в качестве константного выражения.

Нет другого синтаксиса для указания значения по умолчанию для компонента.

Параметр типа kind может присутствовать в константном выражении, поэтому компоненты с границами, заданными параметром kind этого типа, могут иметь инициализацию по умолчанию.

0 голосов
/ 25 мая 2020

Вы обнаружили ошибку в разных компиляторах. Ваш код соответствует стандарту. Немного уточняя код, следующее должно вывести «2 2 2».

program main

implicit none
!
! F2018, 7.5.1, page 64: A derived type can be parameterized by one or
! more type parameters, each of which is defined to be either a kind
! or length type parameter and can have a default value.
!
! F2018, 7.5.3.1, page 69: A type parameter may be used as a primary in
! a specification expression (10.1.11) in the derived-type-def.
!
! 10.1.11 Specification expression (page 156)
! ...
!    R1028 specification-expr  is scalar-int-expr
!
! C1010 (R1028) The scalar-int-expr shall be a restricted expression.
!
! A restricted expression is an expression in which each operation is
! intrinsic or defined by a specification function and each primary is
! ...
! (13) a type parameter of the derived type being defined,
!
type data2(n)
   integer, len :: n
   integer :: array(n) = 2
end type data2

type(data2(n=3)) :: a

print *, a%array  ! This should print 2 2 2

end program main

gfortran компилирует код, но печатает «0 0 0», поэтому в gfortran есть ошибка в применении инициализации компонента.

0 голосов
/ 25 мая 2020

Вы можете создать конструктор, который принимает параметр длины для создания объекта

module datatypes

type data2(n)
    integer, len :: n
    integer :: array(n)
contains        
    procedure, pass :: data2_fill2
end type

interface data2
    module procedure new_data2
end interface

contains
    subroutine data2_fill2(this)
        class(data2(*)) :: this
        this%array = 2
    end subroutine
    function new_data2(n) result(r)
        integer, intent(in) :: n
        type(data2(n)) :: r
        call r%data2_fill2()
    end function
end module

program Main
use datatypes
    type(data2(3)) :: mydata

    mydata = data2(100)

    print *, "Size of array ", size(mydata%array)

    if( mydata%array(1) /= 2) then
        print *, "Something went wrong"
    end if


end program
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...